게시글
질문&답변
안녕하세요!! 질문있습니다!!
그냥 단순히 컬럼에 article_id를 넣어줌으로써 테이블간에도 연관관계가 맺어졌다고 볼 수 있나? 라는 의문이 들어서 여쭤본거긴 합니다. 강사님 설명 들으니 이해가 되네요 comment 테이블에서 article_id를 참조함으로써 연관관계가 맺어진걸 알 수 있는데, 그럼 혹시 제약조건을 걸지 않는 이유가 뭘까요?배우는 입장으로서 학습할 때 제약조건을 걸어야 참조 무결성을 유지한다고 알고있는데 실무에서는 제약조건없이 참조만 하는 이유를 알고싶습니다
- 0
- 3
- 198
질문&답변
별도의 쓰레드를 만드는 원리
안녕하세요.. 질문과는 상관없는 내용이지만 멀티 쓰레드에 대해서 공부중이라고 해서 댓글 남겨요!! 혹시 인프런에서 수강중인 멀티쓰레딩에 대한 강의를 듣고 계시다면 추천해주실 수 있나 해서 댓글납깁니다!!
- 0
- 3
- 365
질문&답변
만약에 여러사람과 협업한다고 가정시에
@PostMapping("/upload") public String saveFile2(@RequestParam String itemName, @RequestParam MultipartFile file, HttpServletRequest request) throws IOException { String mainDir = System.getProperty("user.dir") + fileMainDir; Path mainDirPath = Paths.get(mainDir); if(!Files.exists(mainDirPath)) Files.createDirectories(mainDirPath); Path path = Paths.get(mainDir, file.getOriginalFilename()); file.transferTo(path.toFile()); return "upload-form"; } }fileMainDir은 application 설정파일에서 지정한 경로 변수이고, System.getProperty("user.dir")함수를 사용하면 현재 프로젝트가 실행중인 디렉토리의 절대 경로를 찾아내서 반환해준다고 하네요.저는 이런방식으로 해결했는데 혹시 다른방식이나 베스트 프랙티스가 있을까요??
- 0
- 2
- 263
블로그
전체 42025. 03. 30.
0
워밍업 클럽 3기 BE 클린코드&테스트 - 4주차 발자국
Layered Architecture 구조의 레이어별 테스트 정리Persistence Layer특징: 데이터를 직접 접근하고 관리하는 계층.테스트 방법: CRUD 중심으로 테스트하되, 비즈니스 로직은 포함하지 않는다.유의점: 테스트 수행 후 데이터 정리(clean-up)를 철저히 해야 한다.Business Layer특징: 비즈니스 로직이 전개되는 중심 계층.테스트 방법: 통합 테스트로 비즈니스 로직의 정확성을 검증하며, 예외 상황 처리에 더 많은 집중이 필요하다.유의점: 예외 케이스를 잘 다루는 것이 개발자의 역량이다.Presentation Layer특징: 외부 요청을 처리하는 계층.테스트 방법: 입력 값의 유효성을 검증하며, 하위 레이어는 모킹 처리하여 독립적으로 테스트한다.유의점: 유효성 검증이 어느 레이어에서 이루어져야 하는지 신중하게 고민해야 한다.Mocking에 대한 이해와 활용Mock 객체를 활용하는 것이 단위 테스트의 핵심이라고 할 수 있다. Mock 객체는 실제 객체의 행위를 대신할 수 있는 가짜 객체로, Mockito 같은 라이브러리를 활용해 쉽게 만들 수 있다. 중요한 것은 Mock 객체를 사용할 때, 실제 객체의 동작을 완벽하게 대체한다고 생각하지 말고 의심하고 검증하는 태도를 유지하는 것. 특히, Mock 객체의 역할과 Stub의 역할을 동시에 수행할 수 있다는 점을 배웠다.또한, Mocking이 들어가는 순간 그것은 단위 테스트라는 개념을 다시 한번 되새길 수 있었습니다.@Mock, @MockBean, @Spy, @SpyBean, @InjectMocks의 차이@Mock: Mockito에서 단위 테스트를 위한 Mock 객체 생성. 행위 검증이 가능하다.@MockBean: Spring Boot 테스트 환경에서 Mock 객체를 사용하기 위해 Bean을 Mock으로 교체한다.@Spy: 실제 객체를 사용하면서 일부만 Stubbing을 할 수 있다.@SpyBean: Spring Boot 테스트 환경에서 Bean을 Spy 객체로 교체한다.@InjectMocks: @Mock과 @Spy로 생성된 객체를 테스트 대상 객체에 자동으로 주입해준다.테스트 환경의 독립성 유지에 대한 고민테스트의 독립성을 유지하는 것이 얼마나 중요한지를 다시 한번 느낄 수 있었다. 테스트 데이터가 @BeforeEach로 설정되면 모든 테스트에서 공유되는 데이터로 사용될 수 있다. 하지만, 테스트가 추가되거나 변경되면 해당 데이터가 정확히 어떤 테스트에서 필요한 것인지 혼란을 초래할 수 있다. 개인적으로는 각 테스트에서 필요한 데이터를 명시적으로 작성하는 방식이 더 명확하고 안전하다고 생각한다.특히 예외적인 상황을 테스트하거나, 특정 요구사항을 검증할 때 명시적으로 데이터를 정의하는 것이 더 적합하다고 판단했다.Spring REST Docs와 SwaggerSpring REST Docs와 Swagger는 문서화를 위한 좋은 도구들이다.둘 다 장단점이 존재하므로, 팀의 환경과 목적에 맞게 적절히 선택하는 것이 중요하다고 생각한다.Spring REST Docs: 코드 기반으로 문서를 자동으로 생성하며, 정확성과 신뢰도가 높다.Swagger: UI 기반의 문서화가 가능하고 사용자가 직접 API를 테스트할 수 있는 장점이 있다.회고와 느낀 점이번 강의를 통해 테스트의 중요성과 모킹의 활용 방법을 깊게 배울 수 있었다.특히, 단위 테스트와 통합 테스트를 구분해서 작성하는 방법을 익힌 것이 큰 성과라고 생각한다.테스트 코드를 작성할 때 각 레이어의 특징을 이해하고, 적절한 테스트 방법을 적용하는 것이 중요하다는 것을 느꼈다.또한, Mock 객체를 사용할 때는 항상 ‘정말 잘 모킹이 되었는가?’ 라는 의심을 가지고 테스트를 설계해야 한다고 생각한다.앞으로는 테스트를 작성할 때도 더 효율적이고 의미 있게 작성하도록 노력해봐야겠다. 출처 : https://inf.run/EBCNE
백엔드
2025. 03. 23.
0
통합테스트와 단위테스트 그리고 TDD
이번 3주차 발자국을 작성하기에 앞서서, 저는 다른 스터디원분들이 작성해준 테스트 시 사용되는 애노테이션의 사용법과 각 차이점 보다는 통합 테스트와 단위테스트 그리고 TDD를 수행해야하는 근본적인 이유에 대해서 작성하였으며 이를 통해 얻고자 하는 것은 궁극적으로 무엇인가에 대해서 작성하였습니다.통합 테스트란??메서드가 어떠한 상황에서 어떻게 작동해야된다.라는 것을 보장하는 것이 단위테스트라면 통합테스트는 A객체와 B.객체가 만나서 협력 시 어떻게 동작한다라는 것을 보장하기 위해서 수행하는 것이다.통합 테스트는 왜 해야하는가?“불안감”때문이다. 정확히 말하면 시스템 전체가 의도한 대로 작동하는지 확인하고 신뢰할 수 있는 상태로 배포하기 위해서이다. 통합 테스트를 해야하는 근본적인 이유는 아래와 같다.“기능은 우리의 의도대로 작동하지 않을 수 있다.”각각의 모듈은 단위테스트를 통해서 잘 돌아가는 것을 보장받았지만 여러 모듈이 협력해 하나의 트랜잭션을 완벽히 수행해야할 때 우리의 생각과는 다르게 동작할 수 있다.실제 연결되면 의존 관계, 데이터 흐름, 부작용등으로 인해 예상 밖의 오류가 발생할 수 있다.“배포시 문제를 일으킬 수 있는 불안감”단위 테스트는 개별 단위만 보장할 뿐 전체 흐름은 검증하지 않는다.실사용자 시나리오에서 시스템이 어떻게 반응하는지 확인해야만 안정적으로 배포가 가능하다.통합 테스트는 바로 실제 사용 시나리오를 기반으로 한다.통합 테스트의 본질적인 목적전체 시스템이 유기적으로 동작하는지에 대한 신뢰성을 검증하는 것API, DB, 외부 서비스등 데이터 흐름을 확인하며 모듈간 상호작용 확인단위 테스트로 잡지 못하는 복합적인 문제 사전 탐지 및 버그 사전 발견배포 안정성 확보단위 테스트란?하나의 함수, 메서드, 클래스와 같은 가장 작은 코드 조각이 예상한 대로 작동하는지 검증하는 테스트이다.가장 좁은 범위의 테스트일반적으로 입력 → 기대 결과 비교외부 시스템에 의존하지 않고 격리된 환경에서 수행되어야 한다. 외부 시스템을 의존할 경우 Mock으로 대체단위 테스트는 왜 해야하는가?로직 오류, 오타, 예외처리 누락 등 언제든지 발생 가능한 작은 범위의 버그를 잡아내기 위해서 수행한다.코드가 많아지고 길어질수록 발생하는 “다른 곳의 영향은 없나” 하는 공포가 커지게 되고, 이는 팀 전체에 끼치게ㅔ 된다.시간이 흐른뒤에 코드를 보게 되면 믿음이 흐릿해지고 제대로 작동하는지에 대한 의구심이 들게 된다.위와 같은 사유로 단위테스트는 작성되어 팀 전체의 심리적 불안 요소를 제거하거하고, 코드를 “검증된 사실” 및 “프로젝트를 설명하는 문서”와 같은 존재가 되어야 한다.단위 테스트는 “이 코드가 나의 의도대로 동작한다” 라는 것을 기계적으로, 반복 가능하게 자동으로 입증하는 절차이며 리팩토링 시 언제든지 업데이트가 가능한 살아있는 문서가 된다.TDD란?“테스트 코드를 먼저 작성(문서를 먼저 작성)하고, 해당 테스트를 통과시키기 위한 실제 코드를 작성하는” 개발 방식이다.TDD는 3단계의 사이클이 존재하는데 Red, Green, Refactor단계로 나뉘게 된다.Red: 먼저 해당 기능에 맞는 시나리오 테스트를 작성한다.(실제 프로덕션 코드가 없기 때문에 실패한다.)“정확히 어떤 동작을 수행해야 하나?”를 먼저 고민하게 만듦으로써 설계 사고를 유도한다.Green: Red 테스트 코드가 성공할 수 있도록 실제 프로덕션 코드를 작성한다.해당 단계에서는 Red에서 실패한 테스트 코드가 성공만 하면 되기 때문에 최대한 빠르게 작성한다.사고의 깊이를 줄이고, 가장 단순한 형태의 로직만 나열하여 성공하도록 만든다.완벽하게 작성하는 것이 아닌 작동이 가능한 코드를 만드는 것이 원칙이다.Refactor: Green에서 휘갈겨 작성한 코드를 Refactoring하는데 있어서 Red에서 작성한 테스트 코드는 건들지 않는다.중복을 제거하고, 가독성을 향상시키는데 초점을 둚으로써 코드 품질을 개선한다.테스트가 통과되었기 때문에 리팩토링 과정에서 테스트가 실패할 경우 빠른 피드백을 얻을 수 있다.
백엔드
・
워밍업클럽3기BE
・
클린코드&테스트코드
2025. 03. 16.
0
👣 리팩토링을 대하는 자세와 단위 테스트를 대하는 자세
🎯 코드의 의도를 명확하게 표현하기코드를 작성할 때 가장 중요한 요소중 하나는 “코드가 무엇을 하는지”명확하게 나타내는 것.코드 자체가 설명적이여야 하며, 주석에 의존하지 않아야 한다코드는 변한다. 즉 소프트웨어는 발전하며 코드는 동적이지만 주석은 변하지 않는다.좋은 네이밍은 코드의 가독성을 높이며 함축적인 의미를 담는 것이 중요하다.그렇다고 해서 너무 함추적인 의미를 담거나 줄임말은 피해야 한다.함수와 변수를 의미 있는 이름으로 정의하면 코드를 읽는 입장에서도 쉽게 이해할 수 있다.한개의 함수는 한가지 책임만 가져야 하며, 여러가지 기능을 포함하지 않도록 해야한다.🎯 비즈니스 로직이 자연스럽게 녹아있는가?비즈니스 로직은 도메인의 개념을 반영해야 한다현재 내 프로젝트의 요구사항 및 도메인 개념이 들어가 있어야 한다.도메인 용어를 코드에서 그대로 활용하는 것이 가독성 향상에 도움이 된다.🎯 변수와 메서드의 배치는 읽는 흐름을 고려관련된 변수와 메서드는 가까운 곳에 배치하는 것이 좋다.상위 개념에서 하위 개념으로 자연스럽게 흐르도록 정리해야 한다.공개메서드의 배치도 중요도롤 따라서 정리한다 → 객체의 상태를 변경하는 메서드는 상위에, 그 다음 판별 메서드 그 다음 조회 메서드 순으로 중요도를 나눠 배치하자.비공개 메서드는 공개메서드의 언급된 순서대로 배치하고, 공통으로 사용하는 메서드라면 하단에 두자.🎯 테스트 하기 쉬운 영역과 어려운 영역 나누기순수 함수 중심으로 설계하고, 테스트가 어려운 영역은 Mocking 활용하기테스트 하기 쉬운 영역구분하기순수함수(특정 입력이 특정 출력을 내는 경우)외부 의존성이 없는 메서드테스트 하기 어려운 영역DB 네트워크, 파일 입춥력 등 외부 시스템을 사용하는 코드static 또는 private 메서드환경 변수에 의존하는 코드외부 시스템을 사용하는 코드의 단위테스트는 Mock → 가짜 객체를 이용하여 의존성을 주입받고 테스트를 진행할 수 있다.📚 회고리팩토링은 필수가 아니라 “습관"이다.리팩토링은 “나중에 하는 것이 아니라, 항상 개선할 수 있는 습관” 으로 가져가야 한다.코드가 동작한다고 해서 “좋은 코드”가 아니다. 더 읽기 쉬운 코드 , 유지보수 하기 쉬운 코드가 되어야 한다.리팩토링에 있어서의 개발자의 태도“이 정도면 되겠지?”에서 멈추는 것이 아닌 “이 코드가 우리 프로젝트의 도메인 개념을 잘 설명하고, 가장 직관적인가?”를 고민하자리팩토링은 가독성을 최우선으로 둔다가독성이 높은 코드는 유지보수가 쉽고, 버그를 줄일 수 있다리팩토링을 할 때는 테스트가 필수이다단위 테스트 없이 리팩토링하면 코드가 망가졌는지 확인할 방법이 없다.그리고 무섭다. 단위 테스트 코드 없이 리팩토링 하는 것 자체가 무섭다.단위 테스트가 없는 코드를 리팩토링한다면 그 전에 먼저 테스트를 작성하자.리팩토링을 할 때는 단계적으로 진행하자변경할 때마다 단위 테스트를 실행하여 문제가 없는지 확인해야 한다.단위 테스트는 개발자로서 “코드 품질을 지키는 무기”다.단위 테스트는 단순한 체크리스트가 아니라 개발자가 “코드를 망가뜨리지 않도록 보호”하는 방패라고 생각하고 작성하자단위 테스트가 잘 갖춰진 프로젝트는 리팩토링이 자유롭다.실제로 나는 TDD보다 기능을 먼저 개발한 뒤 해당 기능이 내가 예상한대로 잘 작동하는지 안하는지 테스트 코드를 작성하는데, 다양한 케이스를 보호하는 테스트 코드를 작성하지 못하더라도, 허접한 테스트 코드라도 있는것이 낫다고 생각한다. 그 허접한 테스트 코드가 나를 살려줄 때도 많이 있었기 때문…그리고 오히려 테스트 코드가 없다면 디버깅에 더 많은 시간이 소요된다. BDD 스타일로 시나리오를 확인한뒤 테스트 코드를 보면서 데이터의 흐름을 유추할 수 있다. 🗣 개발자의 마음가짐✅ 테스트는 문서다.테스트는 코드의 사용법을 가장 정확하게 설명한다.테스트는 코드의 동작을 명확하게 문서화한다. 어떤 상황에서 어떻게 동작한다와 같은 동작을 명확하게 녹여낸다.테스트는 코드의 유지보수를 돕는 최신 문서다.✅ 리팩토링을 대하는 자세리팩토링은 코드 품질을 높이는 습관이다.코드의 가독성을 최우선으로 둔다.테스트 없이 리팩토링하지 않는다.과한 추상화를 피하고 실용적인 접근을 한다.✅ 단위 테스트를 대하는 자세단위 테스트는 “개발자의 무기”다.실패하는 테스트를 통해 버그를 예방한다.Happy Case + 예외 Case를 모두 테스트한다.테스트가 어려운 경우, Mocking을 활용한다.
백엔드
・
워밍업클럽3기BE
2025. 03. 07.
0
SOLID의 모든 원칙은 결국 "추상화"로 수렴한다.
1주일 동안의 강의 내용결론부터 말하자면 SOLID원칙 모두 구체적인 구현에 의존하지말고 추상화를 통해 유연한 설계를 하라는 점에서 공통된다.1⃣ OCP (개방-폐쇄 원칙: Open-Closed Principle)“확장은 가능하지만, 기존 코드는 수정하지 말것”새로운 기능을 추가할 때 기존 코드를 변경하지 않고, 새로운 기능을 담당하는 객체를 생성하고 새로운 기능과, 기존 기능을 확장할 수 있도록 인터페이스를 활용하여 설계를 가능하게 해야한다.✅ 추상화 적용 → Shape 인터페이스를 만들고 Circle, Rectangle 등이 이를 구현하면 Shape을 확장해도 기존 코드 변경 없이 새로운 도형을 추가할 수 있음.interface Shape { double area(); } class Circle implements Shape { private double radius; public Circle(double radius) { this.radius = radius; } public double area() { return Math.PI * radius * radius; } } class Rectangle implements Shape { private double width, height; public Rectangle(double width, double height) { this.width = width; this.height = height; } public double area() { return width * height; } } // 기존 코드 수정 없이 새로운 도형 추가 가능 해당 부분에서 Triangle과 같은 새로운 기능이 추가 되어도, 기존의 코드를 수정하는 것이 아닌 Shape를 구현할 수 있게 해주면 된다.2⃣ ISP (인터페이스 분리 원칙: Interface Segregation Principle)“인터페이스는 클라이언트가 사용하지 않는 기능을 강요해서는 안된다”하나의 거대한 인터페이스, 즉 하나의 개념에 대해서 그 개념을 모두 통괄할 수 있는 인터페이스를 만드는 것이 아닌 역할별로 분리된 작은 인터페이스를 설계해야 한다.interface Bird { void fly(); } class ButterFly implements Bird { void fly() { System.out.println("fly"); } } class Penguin implements Bird { void fly() { System.out.println("can't fly...only walk"); } } ✅ 현재 Penguin은 날지 못하지만 Bird란 추상적인에 속해 fly를 강요받는다…✅ 추상화 적용 → 여러 개의 인터페이스로 분리하여 불필요한 의존성을 줄이고, 유연한 설계 가능.interface Fly { void fly(); } interface Walk { void walk(); } 이렇게 기능을 작은 단위의 인터페이스로 쪼개서 사용하면 된다.3⃣ LSP (리스코프 치환 원칙: Liskov Substitution Principle)“하위 클래스는 상위 클래스의 기능을 대체할 수 있어야 한다”상위 클래스 타입으로 하위 클래스를 사용해도 정상적으로 동작해야 한다. 이를 위해 추상화된 부모 클래스를 만들고 이를 확장하는 하위 클래스 들이 부모의 행위를 그대로 유지해야 한다.✅ 추상화 적용 → 하위 클래스는 상위 클래스의 동작을 유지해야 함.class Bird { void fly() { System.out.println("Flying..."); } } class Sparrow extends Bird { } // 정상적으로 동작 class Ostrich extends Bird { @Override void fly() { throw new UnsupportedOperationException("I can't fly!"); } // LSP 위반 } ✅ Ostrich는 Bird이지만 날 수 없음 → fly()를 강제하는 구조 자체가 잘못됨✅ 이를 해결하려면 Flyable 인터페이스를 분리하여, 날 수 있는 새만 이를 구현하도록 해야 함4⃣ DIP (의존성 역전 원칙: Dependency Inversion Principle)“상위 모듈이 하위 모듈에 의존하는 것이 아니라 둘 다 추상화(인터페이스)에 의존해야 한다.”즉 구체적인 클래스가 아니라 인터페이스나 추상 클래스를 사용하여 의존성을 주입받아야 한다.interface Repository { void save(); } class MySQLRepository implements Repository{ void save() { System.out.println("MySQL Save Processing"); } } class JPARepository implements Repository { void save(); } Repository라는 추상화를 적용시켜서 이를 구현한 구현체로 MySQL, JPA, MongoDB… 새로운 DB가 추가 되어도 구현체에 직접 의존하는 것이 아닌 상위 모듈을 의존성 주입받아 런타임에 구현체를 동적으로 변경할 수 있도록 구현한다.결론: 모든 원칙이 “추상화”로 수렴한다.📌 OCP (개방-폐쇄 원칙) → 추상화(인터페이스)를 이용하면 기존 코드를 수정하지 않고도 확장 가능📌 ISP (인터페이스 분리 원칙) → 불필요한 의존성을 제거하고, 필요한 기능만 제공하는 인터페이스 설계📌 LSP (리스코프 치환 원칙) → 추상화를 잘못하면 하위 클래스가 부모 클래스를 대체하지 못함 → 올바른 추상화가 중요📌 DIP (의존성 역전 원칙) → 구체적인 구현이 아니라 추상화(인터페이스)에 의존해야 함.📌 SRP (단일 책임 원칙) → 클래스는 단 하나의 책임만을 가지고 있어야 하고, 해당 클래스가 변경될 경우 그 이유는 오로지 책임에 의한 것이어야 함. → SRP 또한 각 클래스가 하나의 역할만 수행하므로 자연스럽게 추상화가 이루어지고, 다른 SOLID 원칙들고 적용하기 쉬워진다.1주일 동안의 회고깊은 내공이 느껴지는 강의를 듣고 과연 나의 코드는 읽기 좋은 코드는 못 될지 언정 과연 읽을만 한가?라고 생각하며 여태 했던 개인프로젝트들과 팀 프로젝트의 코드들을 살펴보았고, 이번 일주일 동안 강의에서 배운 SOLID원칙을 활용한 추상과 구체, 논리와 사고의 흐름 및 사고의 깊이 줄이기 같은 요소들을 하나둘씩 살펴보았다. 긴 시간은 투자하지 못했지만 OCP와 DIP, SRP 원칙만큼은 쉽게 눈에 보이는 레벨에서 고쳐나갈 수 있다고 생각하고 나름 만족할 만큼 적용했다고 생각한다. 나는 개인적으로 객체지향이라는 개념 자체가 너무 추상화되어있는 표현 혹은 단어라고 생각한다. 이것에 대한 개념에 대해서 알고있어도 초보자 레벨에서 이를 적용시키기란 매우 어렵고, 사람마다 그 기준이 너무나도 다르기 때문에 정답은 없는 것 같다라는 생각이 든다. 정답은 없지만 정답에 가까운 그런 방식은 있을 것이라고 생각한다. 나는 사실 내가 객체지향을 초보자 레벨에서는 나름 잘 적용해왔다고 생각해 왔었다. 그 이유는 우테코 프리코스를 2번이나 해보면서(2번 다 떨어졌다…) 그리고 실제로 친한 중고등학교 친구가 배민에서 개발자로 일하기 때문에 친구가 일주일에 한번씩 코드리뷰도 해주었었다.(많이 혼났었지만…) 나름 객체지향이라는 개념과 SRP, OCP, DIP라는 개념은 실무에서도 실제로 가장 강력한 무기가 될 수 있기에 잘 지켜왔었다고 생각한다. 결론은 “추상화”가 가장 중요한데.. 이부분이 제일 어렵다. 그래서 코드를 작성할 때 이 부분만큼은 옆에 메모장에 띄워놓고 익숙해질 때까지 해야한다 라고 생각한다.1. 코드는 적절한 수준에서 추상화되어야 한다.핵심 로직을 메서드 또는 클래스로 분리하여 한 가지 역할에 집중하도록 한다.코드의 유연성과 확장성을 높이기 위해서는 인터페이스와 구현을 분리해야한다.네이밍을 통해 역할을 명확하게 전달한다2.논리와 사고의 흐름코드는 논리적으로 자연스럽게 읽혀야 한다.코드의 동작 순서가 사람이 생각하는 방식과 유사해야 한다.조건문과 루프의 배치를 신중히 고려해야 한다.불필요한 상태 변경을 줄여야한다.여기서 사고의 깊이가 가속화 된다. 상태가 변경되는 시점을 기준으로 변경된걸 인치한 채 코드를 따라가야 한다.3. 사고의 깊이 줄이기한번에 이해할 수 있는 코드가 가장 좋은 코드다Simple is best!!!조건문을 단순화 하여라.그리고 부정문(!)을 사용할 경우 메서드명으로 그 의도를 명확히 나타내는쪽으로 코드를 작성해라이미 여기서 상태의 변경이 일어난 상태로 if문 안의 로직을 들어간다.메서드를 작게 나눠라.작게 나누지 못할 경우 추상화 혹은 다른 클래스의 책임을 나누는 것을 고려하라.분명 나는 SRP원칙을 잘 지켰다고 생각한 상태에서 좀 두꺼운 메서드를 나누려고 할 때 나누지 못하겠다면 SRP원칙을 어긴건 아닌지 다시 보자.Early Return 패턴을 통해 중첩을 줄이자.결론적절한 추상화 → 코드가 마치 살아있고 객체지향적인 코드가 나타난다. 이는 코드의 유연성을 높인다.논리적인 흐름 → 코드를 읽을 때 직관적인 이해를 돕기 때문에 유지보수하기 편하고, 소프트웨어의 품질을 높일 수 있다.사고의 깊이 줄이기 → 코드를 한번에 쉽게 파악할 수 있도록 만들기 때문에 유지 보수 및 기능 추가 등등의 비용을 줄일 수 있다.Day2, Day4 미션에 대한 회고Day2 주제 : 추상과 구체에 대한 예시 3~5문장으로 정리하기.[해결 과정]추상과 구체를 어떻게 정의할 것인가?“추상이란 여러 개념을 일반화 하여 표현한 것이며, 구체는 해당 개념을 세부적으로 설명하는 것이다” 라는 사전적인 정의를 먼저 내가 스스로 이해하고 접근 하였다.[접근 방식]일상에서의 추상과 구체의 예시를 찾아 정리하였다.일상 생활에서의 추상추상 → 동물구체 → 개, 고양이, 새, 쥐 … 등등의문 → 개 또한 추상적인 개념이 아닌가….?? 더 나아가서 “진돗개” , “시츄”, “셰퍼드”, “포메라니안”… 등등배운점 : 어디까지가 적절한 추상화인가….??에 대해서 깊이 고민하게 되었다…Day4 주제 : 코드 리팩토링, SOLID에 대한 자기만의 언어로 정리.[해결과정]사고의 깊이 줄이기이번 미션으로 내준 코드는 if ~ esle 그 내부에 또다른 if와 else..객체지향적인 사고if 조건문의 로직 변경하기[접근 방식]복잡한 if문에서 빠져나오는 것이 첫번째라 생각했고, 이는 early return으로 쉽게 해결할 수 있다.getter를 통해 해당 객체의 외부 정보를 빼내와서 외부의 정보와 데이터를 가공하는 로직이 직접적으로 들어나있는 부분들을 객체 내부로 숨기고 캡슐화와 객체의 역할을 정확히 하고 나누는 방향으로 접근했다.그렇게 했을 때 책임과 역할이 객체간에 명확하게 되고, 캡슐화를 지킴으로써 유지보수성이 올라간다고 생각했다.
백엔드
・
워밍업클럽3기BE