박서연
@udadang
수강평 작성수
-
평균평점
-
블로그
전체 9#카테고리
- 백엔드
#태그
- 워밍업클럽
![[워밍업 클럽 4기 - 백엔드] 강의 수료증](https://cdn.inflearn.com/public/files/blogs/171c4ce2-df76-408e-acdd-99c74c74b9e7/KakaoTalk_20250527_195638166.png?w=260)
2025. 06. 21.
0
[워밍업 클럽 4기 - 백엔드] 강의 수료증
[ Readable Code: 읽기 좋은 코드를 작성하는 사고법 - 수료증 ]https://inf.run/Hf92W[ Practical Testing: 실용적인 테스트 가이드 - 수료증 ]https://inf.run/K4s2Y
백엔드
・
워밍업클럽
![[워밍업 클럽 4기 - 백엔드] 4주차 발자국](https://cdn.inflearn.com/public/files/blogs/cbbdb791-ab67-4574-b609-d4a81319150e/KakaoTalk_20250527_195638166.png?w=260)
2025. 06. 21.
1
[워밍업 클럽 4기 - 백엔드] 4주차 발자국
[인프런 워밍업 클럽 스터디 4기 - 백엔드]강의 출처 :Readable Code: 읽기 좋은 코드를 작성하는 사고법Practical Testing: 실용적인 테스트 가이드4주차 발자국 강의 수강학습 내용 요약Spring & JPA 기반 테스트 : Presentation Layer 테스트(@WebMvcTest, Mock와 Mockito, @MockBean, @RestControllerAdvice, @ExceptionHandler, Spring Bean Validation)Mock을 마주하는 자세 : Mockito로 Stubbing하기, Test Double(Dummy, Fake, Stub-상태검증, Spy, Mock-행위 검증), 순수 Mockito로 검증하기(@Mock, @Spy, InjectMocks), BDDMockito, Classicist VS Mockist더 나은 테스트를 작성하기 위한 구체적 조언 : 한 문단에 한 주제, 완벽하게 제어하기, 테스트 환경의 독립성 보장, 한 눈에 들어오는 Test Fixture 구성(@BeforeAll, @BeforeEach, setUp), Text Fixture 클렌징(deleteAllInBatch, deleteAll), @DynamicTest, 환경 통합하기, private 메서드 테스트 x, 테스트에만 필요한 메서드도 가능함Appendix : 학습 테스트, Spring REST Docs(REST Docs, Swagger, AsciiDoc)Outro : 테스트를 작성하는 마음가짐(시간, 충분한 연습, 테스트 케이스에 대해 생각해보기) 4주차 회고 이번 주는 드디어 테스트 작성 강의를 완강한 주였습니다. Presentation Layer 테스트부터 Mockito를 활용한 테스트 더블까지 다양한 내용을 배우면서, 평소 개념만 어렴풋이 알고 있던 Mock 객체들을 제대로 배울 수 있어서 정말 좋았습니다. 특히 Spring Bean Validation이나 MockMVC 등을 실제로 사용하며 학습하니, 이론만 공부할 때는 애매했던 부분들도 확실히 이해가 되어서 뿌듯했습니다. 또한, 테스트 코드를 작성하면서 자연스럽게 코드 자체의 가독성이나 명확성을 고민하게 되어, 코드 작성뿐 아니라 글쓰기에 대해서도 많이 배울 수 있었습니다.지난 금요일에는 2차 중간 점검 라이브도 진행되었는데, 다른 분들의 Q&A를 들으면서 같이 공부도 되고 다양한 정보도 얻을 수 있어 좋았고, 코드 리뷰를 통해서 다른 분들의 코드를 내 코드와 비교해보고 고칠 점이나 배울 점을 정말 많이 느낄 수 있었습니다. 직접 코드 리뷰를 신청하지는 못했지만, 그럼에도 함께 리뷰하는 것만으로도 여러가지 좋은 아이디어를 얻을 수 있는 시간이었습니다!스스로 칭찬할 점은 이번 주 강의 수강과 미션을 미루지 않고 당일에 잘 해냈다는 점과, 4주간 꾸준히 노력하며 스터디를 무사히 완주했다는 점입니다. 처음에는 제가 잘 따라갈 수 있을 지 조금 걱정되긴 했지만, 포기하지 않고 뭔가를 꾸준히 해내고 성취했다는 사실이 정말 기쁘고 뿌듯했습니다. 아쉬운 점은 스터디를 하면서 좀 더 적극적으로 참여했더라면 좋았을 것 같다는 생각이 듭니다. 특히 코드 리뷰 신청 같은 기회들을 더 적극적으로 활용하지 못한 것이 아쉽습니다. 스터디를 마치면서 돌이켜보면, 그동안 뭔가를 해야 한다고 생각하면서도 자꾸 미루고 시작조차 하지 못하던 나 자신에게 변화를 줄 수 있는 좋은 계기가 된 것 같습니다. 스터디를 통해 클린 코드와 테스트 코드에 대해서도 많이 배웠고, 무엇보다 꾸준히 무언가를 해나가는 습관 또한 형성하게 되어 좋았습니다. 또한, 다른 분들의 발자국을 보며 여러 가지 다양한 생각을 접할 수 있어서 즐겁고 유익했습니다. 이번 스터디를 통해 얻은 것을 앞으로 실제 프로젝트에서도 적극적으로 적용하며 더 성장하고 싶습니다. 미션미션 해결 과정 미션 5 (Day16) : 이번 미션에서는 Layered Architecture의 각 레이어가 어떤 책임을 가지는지 스스로 정리해보았습니다. Controller, Service, Repository 각각의 역할과 테스트 방법을 실제 사용 흐름을 떠올리며 정리했고, MockMvc, 단위 테스트, 통합 테스트가 어느 레이어와 어울리는지도 고민하며 정리했습니다. 단순히 암기하는 게 아니라, 내가 다른 사람에게 직접 설명하듯이 이해 중심으로 써보려고 노력했습니다.미션 6 (Day18) : 이번 미션에서는 Mockito의 주요 어노테이션인 @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 각각의 특징과 차이를 정리해보았습니다. 스프링 환경 여부나 진짜 객체인지 여부, 주입 방식 등 조건에 따라 어떤 상황에서 어떤 어노테이션을 써야 할지 더 정확하게 구분할 수 있게 되었고, 지금까지 흐릿했던 개념들이 많이 정리되었습니다.또 테스트 흐름을 명확히 하려고 각 테스트 항목을 @BeforeEach, given절, when절 구조에 맞게 나누어 배치해봤습니다. 예를 들어 댓글 테스트에서는 공통적으로 필요한 사용자와 게시물 생성을 @BeforeEach에 미리 두고, 테스트마다 필요한 사전 작업은 given에, 핵심 동작은 when에 넣어서 흐름을 더 읽기 쉽게 구성했습니다. 회고이번 주 미션을 하면서 테스트 코드가 단순히 결과를 확인하는 도구가 아니라, 기능을 이해하고 구조를 설계하는 데 꼭 필요한 도구라는 것을 다시 한 번 느꼈습니다. 특히 레이어별 역할을 직접 정리하면서, 내가 작성하는 코드가 어떤 위치에서 어떤 책임을 가져야 하는지 더 명확하게 구분할 수 있었고, 앞으로 코드 작성 시에도 이런 기준을 계속 의식하게 될 것 같습니다.Mockito 어노테이션도 이번 기회에 비교해 정리하면서 그동안 헷갈렸던 부분들이 한 번에 정리되었고, 테스트 흐름을 given-when-then 구조로 나누어 작성해보면서 테스트 코드 자체가 문서처럼 읽히게 만드는 것도 중요하다는 점을 알게 되었습니다. 처음에는 주석으로만 흐름을 표시했던 코드들을 어떻게 정리할지 막막했지만, 테스트의 목적에 집중하며 구조를 잡아가는 과정이 점점 익숙해졌고, 그 안에서 테스트가 곧 설계와 연결된다는 감각도 생겼습니다.그동안 미션을 진행하며 매번 배운 내용을 복습하고, 개념을 내 언어로 정리해보는 과정 자체가 학습에 큰 도움이 되었고, 직접 코드를 작성하고 흐름을 따라가며 '이제는 진짜 이해했다'는 자신감도 생겼습니다. 앞으로도 기능 구현과 테스트를 함께 이어가며, 테스트를 설계의 나침반처럼 활용할 수 있도록 꾸준히 연습하고 습관을 쌓아가고 싶습니다!!
백엔드
・
워밍업클럽
![[워밍업 클럽 4기 - 백엔드] Day18 미션](https://cdn.inflearn.com/public/files/blogs/7e2d2f1f-e8ce-4785-a3a6-55ab4bd48d1c/KakaoTalk_20250527_195638166.png?w=260)
2025. 06. 17.
0
[워밍업 클럽 4기 - 백엔드] Day18 미션
[인프런 워밍업 클럽 스터디 4기 - 백엔드]강의 출처 :Readable Code: 읽기 좋은 코드를 작성하는 사고법Practical Testing: 실용적인 테스트 가이드Day18 미션 1 :Mockito 어노테이션 (@Mock, @MockBean, @Spy, @SpyBean, @InjectMocks) 차이점 정리하기. @MockMockito에서 사용하는 어노테이션으로, 테스트 코드 안에서 가짜 객체를 만들어줌실제 객체처럼 사용할 수 있지만, 내부 동작은 하지 않고 필요한 동작만 지정해서 사용함Mockito 단독으로 사용할 때는 설정이 필요함스프링 환경과는 무관하고, 순수한 단위 테스트에서 많이 사용됨@MockBean스프링 테스트 환경에서 mock 객체를 등록할 때 사용하는 어노테이션기존에 스프링 빈으로 등록돼 있는 객체를 mock 객체로 바꿔서 테스트에 사용함@SpringBootTest 나 @WebMvcTest 같이 스프링 컨텍스트를 여는 테스트에서 사용 가능자동으로 스프링 컨테이너에 등록되고, @Autowired 같은 방식으로 주입됨@Spy진짜 객체를 감싸서 사용하는 Test Double원래 동작은 유지하면서, 필요한 일부만 Stubbing 해서 바꿔 쓸 수 있음mock보다 실제 객체에 더 가까운 형태라, 상태를 함께 확인하거나 부분 제어가 필요한 경우에 사용@Mock과 마찬가지로 @ExtendWith(MockitoExtension.class)가 필요함@SpyBean스프링 테스트 환경에서 사용하는 @Spy 형태기존 스프링 빈을 spy로 등록하고, 진짜 동작은 유지하면서 필요한 부분만 바꿔서 사용할 수 있음인터페이스에 적용할 경우, 구현체가 반드시 컨테이너에 등록돼 있어야 오류가 나지 않음테스트 중 일부 메서드는 실제로 실행하고, 일부는 stubbing 하고 싶을 때 사용할 수 있음@InjectMocks@Mock이나 @Spy로 만든 객체들을 주입받는 테스트 대상 클래스에 붙이는 어노테이션생성자, 필드, setter 등을 통해 적절한 위치에 의존성을 자동으로 넣어줌테스트 대상 객체를 직접 생성하지 않아도 되고, mock 객체들로 알아서 조립해주는 역할이 어노테이션만으로는 동작하지 않고, @Mock이나 @Spy가 함께 있어야 의미가 있음 Day18 미션 2 :테스트의 각 항목을 @BeforeEach, given절, when절에 배치해보기. [수정한 코드]@BeforeEach void setUp() { 사용자 생성에 필요한 내용 준비 (1-1, 2-1, 3-1) 사용자 생성 (1-2, 2-2, 3-2) 게시물 생성에 필요한 내용 준비 (1-3, 2-3, 3-5) 게시물 생성 (1-4, 2-4, 3-6) } @DisplayName(""사용자가 댓글을 작성할 수 있다."") @Test void writeComment() { // given 1-5. 댓글 생성에 필요한 내용 준비 // when 1-6. 댓글 생성 // then 검증 } @DisplayName(""사용자가 댓글을 수정할 수 있다."") @Test void updateComment() { // given 2-5. 댓글 생성에 필요한 내용 준비 2-6. 댓글 생성 // when 2-7. 댓글 수정 // then 검증 } @DisplayName(""자신이 작성한 댓글이 아니면 수정할 수 없다."") @Test void cannotUpdateCommentWhenUserIsNotWriter() { // given 3-3. 사용자2 생성에 필요한 내용 준비 3-4. 사용자2 3-7. 사용자1의 댓글 생성에 필요한 내용 준비 3-8. 사용자1의 댓글 생성 // when 3-9. 사용자2가 사용자1의 댓글 수정 시도 // then 검증 } [해결 과정]댓글에 관한 테스트가 목적이기 때문에, 댓글 작성 전에 사용자와 게시물이 먼저 생성되어 있어야 하는 구조라고 판단하여 공통적으로 필요한 사용자 및 게시물 생성을 @BeforeEach에 넣었습니다. 첫 번째 테스트는 댓글의 작성이 핵심 동작으로, 댓글 생성 전 필요한 과정을 given, 실제 생성을 when에 배치했습니다.두 번째 테스트는 이미 작성된 댓글을 수정하는 상황이기 때문에, given에 댓글 생성까지 포함하고, when에서는 수정 동작만 수행했습니다.세 번째 테스트는 댓글 작성자가 아닌 사용자가 수정 시도하는 경우이므로, given에서 별도의 사용자와 댓글을 생성한 후, when에 타인의 댓글을 수정하는 동작을 넣었습니다.
백엔드
・
워밍업클럽
![[워밍업 클럽 4기 - 백엔드] Day16 미션](https://cdn.inflearn.com/public/files/blogs/22075063-7c2c-485a-98b6-b9255770302c/KakaoTalk_20250527_195638166.png?w=260)
2025. 06. 15.
0
[워밍업 클럽 4기 - 백엔드] Day16 미션
[인프런 워밍업 클럽 스터디 4기 - 백엔드]강의 출처 :Readable Code: 읽기 좋은 코드를 작성하는 사고법Practical Testing: 실용적인 테스트 가이드Day16 미션 :Layered Architecture 구조의 각 레이어별 특징과 테스트 하는 방법을 자기만의 언어로 정리하기. 레이어드 아키텍처(Layered Architecture)Persistence Layer특징 : 데이터 접근, 즉 데이터를 저장하거나 조회하는 역할만 담당. 비즈니스 로직 없이 순수하게 CRUD만 처리하는 구조로, 단순하지만 핵심적인 기반이 되는 부분. DB와 직접 맞닿아 있는 만큼 복잡한 로직 없이 깔끔하게 쓰는 게 중요함. 쿼리는 보통 JPA나 QueryDSL을 이용해서 작성하고, 화면에 보여줄 상품 목록 같은 것도 여기서 조건 걸어서 조회함.테스트 : 작성한 쿼리나 메서드가 의도한 대로 동작하는지 확인하는 게 중심. @DataJpaTest랑 H2 같은 임베디드 DB를 써서 빠르게 테스트할 수 있고, 테스트 환경에서는 DB 상태 초기화도 쉬워서 반복 테스트에 적합함. 복잡한 비즈니스 조건은 없지만, 필터링이나 정렬 조건 누락이 생기기 쉬워서 꼼꼼하게 체크해야 함. Business Layer특징 : Persistence와의 상호 작용을 통해 비즈니스 로직을 구현하는 레이어. 예를 들어 주문을 만들거나 재고를 줄이는 등의 서비스 로직이 여기 들어감. 트랜잭션 단위로 묶어서 처리되기 때문에, 예외가 발생했을 때 전체가 롤백되는 구조로 되어 있어야 함. 로직이 복잡해질수록 구조를 명확히 나누는 게 중요함.테스트 : 핵심 로직 단위로 테스트를 작성하고, 하위 레파지토리는 mock으로 대체하는 경우가 많음. 필요한 경우 통합 테스트로 묶어서 전체 흐름을 점검하기도 함. 조건 분기나 예외 상황이 다양해서 실패 케이스도 같이 검증하는 게 좋음. 동시에 일어나는 재고 차감 같은 동시성 이슈도 고민해야 함. Presentation Layer특징 : 외부 요청을 가장 먼저 받는 레이어. 주로 컨트롤러에서 요청 데이터를 받고, 필요한 형식으로 바꿔서 서비스로 넘겨주는 역할. 직접 처리보다는 흐름을 연결해주는 입구 같은 느낌. 입력값 유효성 검사나 간단한 구조 검증은 여기서 해주는 게 일반적이고, 읽기 전용으로 readOnly 옵션을 주는 경우도 있음.테스트 : WebMvcTest와 MockMvc를 써서 실제 요청처럼 테스트하고, 서비스나 하위 레이어는 mock으로 처리함. 응답 상태 코드, 반환 데이터 구조, validation 실패 케이스까지 다양하게 테스트함. Spring Bean Validation 어노테이션을 사용하여 NotNull, NotBlank 같은 검증도 진행하며, 예외 응답은 @RestControllerAdvice랑 @ExceptionHandler 등 사용하여 처리함.
백엔드
・
워밍업클럽
![[워밍업 클럽 4기 - 백엔드] 3주차 발자국](https://cdn.inflearn.com/public/files/blogs/47fbb833-40b3-4151-885f-1ef75048f63c/KakaoTalk_20250527_195638166.png?w=260)
2025. 06. 14.
1
[워밍업 클럽 4기 - 백엔드] 3주차 발자국
[인프런 워밍업 클럽 스터디 4기 - 백엔드]강의 출처 :Readable Code: 읽기 좋은 코드를 작성하는 사고법Practical Testing: 실용적인 테스트 가이드3주차 발자국 강의 수강학습 내용 요약레이어드 아키텍쳐와 테스트 : 레이어 층 (Persistence, Business, Presentation), 관심사의 분리, 통합 테스트Spring / JPA 훑어보기 & 기본 엔티티 설계 : 라이브러리, 프레임워크, 스프링 개념(IoC, DI, AOP), ORM, JPA(어노테이션, 엔티티 설계, Spring Data JPA)Persistence Layer 테스트 : 데이터 접근 역할, JPA Repository 테스트를 하는 이유Business Layer 테스트 : 비즈니스 로직 구현 역할, Persistence와 상호작용(서비스 통합 테스트), 트랜잭션 보장 (예외->롤백), 동시성 고민Presentation Layer 테스트 : 외부의 요청, Mocking 처리하여 단위 테스트, MockMVC, readOnly = true 3주차 회고 이번 주는 요구사항에 맞춰 기능을 하나씩 만들어보고 각 레이어별로 직접 테스트를 작성하며 보낸 시간이었습니다. 스프링 구조(컨트롤러, 레파지토리, 서비스)를 따라가면서 직접 간단한 서비스를 구현하니 그동안 헷갈렸던 부분들도 복습되고, 조금 더 친숙하게 느껴졌습니다. 특히 테스트를 배우기 전에는 왜 굳이 이렇게 하는지 잘 몰랐는데, 직접 테스트를 작성해보면서 어느 부분을 어떻게 테스트해야 하는지 알게 된 점이 정말 좋았습니다. 어노테이션의 정확한 사용법과 이유도 이번 기회에 확실하게 배울 수 있어서 무척 재미있었습니다. 스스로 칭찬할 점은 이번 주에는 미루지 않고 진도표에 맞춰 강의 수강을 잘 마쳤다는 것입니다. 미션도 하루만에 완수할 수 있어서 뿌듯했습니다! 다만 아쉬운 점은 여전히 코드 리뷰 신청에 용기를 내지 못하고 결국 고민만 하다가 신청하지 못했다는 것입니다. 코드와 글쓰기에 자신이 없어서 좋은 기회를 놓친 것 같아 아쉽지만, 그래도 다음 주 라이브를 통해 다른 분들의 고민과 코드를 보며 배워가고 싶습니다. 다음 주가 벌써 마지막이라니 아쉽기도 하고 기대되기도 하는데, 진도표를 따라 강의 수강과 미션들을 밀리지 않고 해내는 것이 목표입니다! 미션미션 해결 과정 미션 4 (Day11) : 이번 미션에서는 코드의 동작 흐름을 따라가면서 직접 단위 테스트를 작성했습니다. 기존 코드의 주요 로직을 테스트하기 위해 실행 흐름을 하나씩 나누고, 주석으로 번호를 붙이며 필요한 메서드를 명확히 구분했습니다. 특히 사용자 입력을 처리하는 InputHandler의 경우, 기존 코드 구조를 크게 바꾸지 않으면서 충돌 문제를 해결하려고 고민하다가 Scanner를 static에서 인스턴스 필드로 변경하고, 반복되는 입력 시뮬레이션 메서드를 리팩토링하여 중복을 제거했습니다. 이용권 목록 처리나 락커 사용 여부 결정, 주문 금액 계산 및 할인 적용 같은 핵심 로직은 모든 경우의 수를 꼼꼼히 체크하고, 결과 값에도 계산 과정을 포함하며, 테스트에도 실제 값을 그대로 사용하며 최대한 현실에 가까운 방식으로 테스트를 작성했습니다. 또한 @DisplayName 작성과 BDD 스타일을 활용하면서 최대한 테스트의 목적과 결과가 잘 드러나는 이름을 짓기 위해 노력하여 테스트 코드의 가독성을 높일 수 있도록 작성했습니다. 회고미션을 진행하며 테스트 코드가 단순히 코드의 확인 도구가 아니라, 코드 구조를 깊게 이해하고 개선하는 데 중요한 역할을 한다는 것을 깨달았습니다. 처음에는 이미 구현된 기능을 뒤늦게 테스트로 작성하다 보니 어떤 부분을 테스트해야 할지 어려웠고, 테스트하기 힘든 구조도 있어서 고민이 많았습니다. 기능과 테스트를 함께 작성하는 방식이 중요한 이유를 이번 미션을 통해 몸소 느낄 수 있었습니다. 특히 동작 흐름을 따라가며 기능에 가장 핵심이 되는 메서드를 찾고, 어떻게 테스트할지 고민하는 과정 자체가 흥미롭고 재미있었습니다. DisplayName과 BDD 스타일을 통해 테스트 코드의 가독성과 명확성을 신경쓰며 개발할 수 있던 점도 좋았습니다. 이번 경험을 통해 테스트가 단순한 검증 수단을 넘어 좋은 설계를 위한 도구이구나 싶은 생각이 들었고, 앞으로 개발 할 때도 기능 구현과 테스트 작성을 병행하며 효율적으로 작업해야겠다는 다짐을 하게 되었습니다.
백엔드
・
워밍업클럽
![[워밍업 클럽 4기 - 백엔드] 2주차 발자국](https://cdn.inflearn.com/public/files/blogs/177aa5b3-b528-449d-9c37-f72ede611963/KakaoTalk_20250527_195638166.png?w=260)
2025. 06. 07.
1
[워밍업 클럽 4기 - 백엔드] 2주차 발자국
[인프런 워밍업 클럽 스터디 4기 - 백엔드]강의 출처 :Readable Code: 읽기 좋은 코드를 작성하는 사고법Practical Testing: 실용적인 테스트 가이드2주차 발자국 강의 수강학습 내용 요약 [ Readable Code: 읽기 좋은 코드를 작성하는 사고법 ]코드 다듬기 : 주석의 양면성(좋은 주석이란), 변수와 메서드의 나열 순서(변수는 사용 순서대로, 공개 메서드 우선, 상태변경/판별/조회), 적당히 패키기 쪼개기, 기능 유지보수하기 (알고리즘 교체, DFS/BFS), IDE 기능리팩토링 실습 : 리팩토링 포인트 (추상화 레벨, 객체의 책임과 응집도, SOLID, 일급 컬렉션)추가 조언 : 능동적 읽기 (리팩토링 하며 읽기), 오버 엔지니어링, 적절한 수준의 클린 코드 사용법 [ Practical Testing: 실용적인 테스트 가이드 ]테스트는 왜 필요할까? : 테스트 코드가 없는 경우 단점, 올바른 테스트 코드 (테스트는 귀찮지만 해야 한다.)단위 테스트 : 수동 테스트 작성해보기, JUnit5 자동 테스트, 테스트 케이스 세분화하기, 테스트하기 어려운 영역을 분리하기 (매번 다른 값에 의존하는 코드, 외부에 영향을 주는 코드), 순수 함수TDD : Red/Green/Refactor, 선 기능구현 후 테스트 (누락, 지연 가능성), 선 테스트 후 기능구현 (유지보수 쉬움, 빠른 피드백), 애자일 방법론테스트는 문서다 : DisplayName (문장으로 작성, 행위에 대한 결과, 도메인 용어), BDD (시나리오 기반, Given/When/Then) 2주차 회고 이번 주는 클린 코드 강의를 완강하고, 테스트 강의로 넘어가는 한 주였습니다. 그동안 클린 코드 강의를 수강하며 코드의 가독성과 구조, 테스트의 중요성에 대해 더욱 깊게 고민할 수 있었고, 단순히 코드가 짧거나 깔끔하다고 좋은 것이 아니라 객체 간의 관계와 책임, 흐름을 명확히 정리하는 것이 훨씬 중요하다는 점을 배웠습니다. 워밍업 클럽을 통해 하나의 강의를 완강하니 무척 뿌듯했습니다. 이제부터 테스트 코드 강의를 시작하게 되었는데, 왜 제대로 된 테스트가 필요한지 납득할 수 있었고, "테스트는 귀찮지만 해야한다."는 말이 가장 크게 와닿았습니다.금요일에는 중간 점검 라이브도 진행되었는데, 다른 분들의 Q&A를 들으며 평소 궁금했던 부분들을 해결할 수 있어 좋았습니다. 다른 분들의 코드를 함께 리뷰하면서 각자의 코드 설계나 이름 짓기 방식이 매우 다양하고 참신한 아이디어들이 많아서 놀라웠고, 제가 미처 생각하지 못한 부분들을 발견하며 많이 배우고 느낄 수 있는 시간이었습니다. 저는 코드를 보여준다는 점이 부끄러워 신청하지 않았는데, 리뷰를 지켜보며 제 코드도 리뷰를 받아보고 싶다는 아쉬움이 들었고 다음 미션에는 용기를 내어 신청해보고 싶다는 생각을 하게 되었습니다.스스로 칭찬할 점은 리팩토링 미션을 열심히 고민하고 끝까지 해냈다는 것입니다. 또한 하나의 강의를 완강했다는 점이 매우 뿌듯하고 칭찬하고 싶습니다! 아쉬운 점은 리팩토링 과정에서 계속 고민하다 보니 강의 진도가 조금씩 밀려서 주말에 몰아서 수강하게 되었다는 점입니다. 다음 주 목표로는 진도표를 따라가며 미루지 않고 강의를 수강하고 싶습니다. 미션미션 해결 과정 미션 3 (Day7) : 세 번째로 하나의 프로젝트를 리팩토링하는 미션을 진행하였습니다. 처음에는 무엇부터 시작해야 할지 막막했지만, 다음 강의 제목들과 적어주신 리팩토링 포인트를 참고하며 하나씩 진행했습니다. 먼저 클래스와 메서드들의 추상화 레벨을 정리했고, 책임이 모호하게 섞여있던 부분들을 명확하게 분리했습니다. 특히 출력 로직의 중복을 제거하며 PassDisplayer 클래스를 도입하여 도메인 객체의 UI 관련 책임을 완전히 분리하였습니다. 또한 InputHandler, OutputHandler, FileHandler도 단일 책임 원칙에 따라 분리하고 인터페이스 중심 설계를 통해 DIP를 적용했습니다. 또한 일급 컬렉션을 도입하여 객체의 응집도를 높이고, 패키지 구조를 도메인별로 명확하게 정리했습니다. 이 과정에서 도메인 내부의 getter를 제거하고 비교 책임을 객체 내부로 이동하는 등 다양한 클린 코드 원칙을 실천했습니다. 회고미션을 진행하며 리팩토링할 부분이 끊임없이 나타나는 경험을 했습니다. 처음엔 리팩토링이 단순한 코드 정리라고 생각했는데, 실제로는 객체 간 협력 관계와 책임을 제대로 설계하는 과정이라는 걸 알게 됐습니다. 특히 어디까지 분리해야 할지, 책임을 어떻게 나눠야 할지 고민하는 과정에서 객체지향 설계의 본질을 깨달았습니다. 시간이 부족하여 어느 정도 마무리 후 미션을 제출하였지만, 계속해서 리팩토링할 부분이 보이는 것이 아쉽기도 했습니다. 그러다 미션 제출 후 수강한 강의에서 "적정 수준을 알기 위해서 한계까지 극단적으로 사용해보자."는 말을 듣고, 정말로 극단적인 리팩토링을 한 번 시도하며 저만의 기준을 찾아가고 싶다는 생각이 들었습니다. 이번 미션을 통해 단순한 기능 구현을 넘어서 '좋은 구조란 무엇인가'를 고민하고, 객체 간 협력과 책임을 처음부터 설계할 수 있는 기반을 다질 수 있었습니다.
백엔드
・
워밍업클럽
![[워밍업 클럽 4기 - 백엔드] 1주차 발자국](https://cdn.inflearn.com/public/files/blogs/9ffaa3be-0f47-4d7f-89c2-39a818e91e01/KakaoTalk_20250527_195638166.png?w=260)
2025. 06. 01.
1
[워밍업 클럽 4기 - 백엔드] 1주차 발자국
[인프런 워밍업 클럽 스터디 4기 - 백엔드]강의 출처 : Readable Code: 읽기 좋은 코드를 작성하는 사고법1주차 발자국 강의 수강학습 내용 요약 추상 : 추상과 구체, 적절한 추상화를 통해 복잡한 데이터와 로직을 단순화, 이름 짓기, 메서드 설계, 추상화 레벨 논리, 사고의 흐름 : Early Return, 사고의 Depth 줄이기, 부정 연산 최소화, 예외 처리, Optional 타입객체 지향 패러다임 : 객체 지향, 관심사의 분리, 객체 설계하기(관심사, 유효성 검증, getter/setter, 필드), SOLID, DIP/DI/IoC객체 지향 적용하기 : 상속보다는 조합을 사용하기, VO와 Entity, 일급 컬렉션, Enum, 다형성, 변하는 것과 변하지 않는 것을 분리하여 추상화(OCP 충족), 도메인 개념 도출 1주차 회고 이번 주는 강의 수강을 시작함과 동시에 클린 코드와 객체지향이란 무엇인가에 대해 열심히 고민한 한 주였습니다. 객체 지향의 개념은 알고 있었지만, 막상 코드에 적용하면 이게 객체 지향인건지 SOLID를 지키는건지 의문이 들었는데 이렇게 직접 뜯어 고쳐가면서 적용해보니 확 와닿는 기분이었습니다. 또한 클린 코드에 대한 내용은 처음 알게 되었는데, 강의를 들으면서 '변수명이 너무 긴데 해석하기 힘든거 아닐까?', '이렇게 작은 것도 메서드로 분리하면 더 복잡해지는 것이 아닌가?' 같은 의문이 들기도 했지만, 실제로 읽기 쉬운 코드로 바뀌는 걸 보며 리팩토링의 중요성을 깊게 깨달을 수 있었습니다.스스로 칭찬할 점은 수업을 들으면서 계속 질문하고 고민하며 강의를 이해하고 찾아보며 내 것으로 만드는 경험을 할 수 있었다는 것이며, 아쉬운 점은 코드를 따라치며 강의를 진행하다보니 생각보다 시간이 꽤 소요되어 뒤로 갈수록 쫓기며 수강했던 점 입니다. 다음 주 목표로는 좀 더 넉넉히 수강 계획을 세워서 충분히 고민하고 생각하며 수강하고 싶습니다! 미션미션 해결 과정 미션 1 (Day2) : 자연 환경과 관련된 예시를 찾던 중, '비가 온다'라는 추상적인 표현이 떠올랐고, 이를 구체적으로 표현해보고자 비가 오는 과정을 조사하며 작성하게 되었습니다. 강사님께서 보여주신 예시와 유사한 형식으로 구성하고 싶어서, 일상에서 자주 사용되는 추상적인 문장을 구체적인 레벨로 세분화할 수 있는 주제를 중심으로 선택하였습니다.미션 2 (Day4) : 수업 중에 배운 내용으로 리팩토링을 진행하였습니다. 우선적으로 Early Return을 사용하여 흐름을 간결하게 하고, 중첩 조건문을 제거하여 사고의 Depth를 줄였습니다. getter 사용을 자제하기 위해 Order 내부에 메서드를 정의하여 캡슐화했고, 메서드의 이름은 의미가 잘 드러나고 명확하게 지어 코드의 직관성을 높였습니다. 또한 부정 연산자 대신 긍정적인 의미를 메서드 이름에 담아 이해하기 쉽게 개선했습니다. 회고각 미션들을 통해 수업 때 배운 내용을 되돌아 볼 수 있는 주제라서 좋았습니다. 특히 미션을 하며 처음으로 리팩토링을 직접 해봤는데, 어떤 방법이 더 나을지 고민하는 과정이 이해에 도움이 된 것 같습니다. 또한 제가 다른 분들의 답변을 보고 비교해가며 더 배워가고 생각해볼 수 있어서 좋았습니다!
백엔드
・
워밍업클럽
![[워밍업 클럽 4기 - 백엔드] Day4 미션](https://cdn.inflearn.com/public/files/blogs/99469baf-d914-4ba5-8179-dbf5be4d7c80/KakaoTalk_20250527_195638166.png?w=260)
2025. 05. 30.
0
[워밍업 클럽 4기 - 백엔드] Day4 미션
[인프런 워밍업 클럽 스터디 4기 - 백엔드]강의 출처 : Readable Code: 읽기 좋은 코드를 작성하는 사고법Day4 미션 1 :읽기 좋은 코드로 리팩토링 [기존 코드]public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; } [리팩토링 후]public boolean validateOrder(Order order) { if (order.isEmptyOrder()) { log.info("주문 항목이 없습니다."); return false; } if (order.isInvalidTotalPrice()) { log.info("올바르지 않은 총 가격입니다."); return false; } if (order.isEmptyCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } return true; } 리팩토링 적용 내용1) Early Return : 불필요한 else를 제거하고, 조건이 맞지 않을 경우 즉시 return 하도록 하여 전체 흐름을 더 간결하게 만들었습니다.2) 사고의 depth 줄이기 : 중첩된 조건문을 제거하고, 각 조건을 평평하게 분리하여 코드의 읽기 흐름이 깊어지지 않도록 개선하였습니다.3) 부정 연산 최소화 : 부정 연산자의 사용을 줄이고, 메서드 이름에 긍정적인 의미를 담아 코드를 직관적으로 이해할 수 있도록 표현하였습니다.4) getter 사용 자제 : getter를 직접 호출하지 않고, Order 내부에 메서드를 정의하여 객체가 스스로 판단하도록 설계하여 캡슐화 원칙을 유지하였습니다.5) 명확한 이름 짓기 : 메서드 이름에 행위와 의미가 잘 드러나도록 하여, 조건의 의도를 한눈에 파악할 수 있도록 리팩토링하였습니다. Day4 미션 2 :SOLID에 대하여 자기만의 언어로 정리 SRP - 단일 책임 원칙 (Single Responsibility Principle)하나의 클래스는 하나의 역할에만 집중해야 한다.여러 이유로 동시에 변경되지 않도록, 변경의 책임을 하나로 제한한다.OCP - 개방/폐쇄 원칙 (Open-Closed Principle)확장에는 열려 있고, 수정에는 닫혀 있어야 한다.새로운 기능이 생겨도 기존 코드를 고치지 않고, 유연하게 확장할 수 있도록 한다.LSP - 리스코프 치환 원칙 (Liskov Substitution Principle)자식 클래스는 부모 클래스가 사용되는 자리에서 자연스럽게 대체 가능해야 한다.상속을 했다면 부모의 역할과 일관된 동작을 유지해야 한다.ISP - 인터페이스 분리 원칙 (Interface Segregation Principle)하나의 큰 인터페이스보다, 역할에 맞게 나눈 인터페이스를 제공하는 것이 좋다.사용하지 않는 메서드를 억지로 구현하지 않도록 필요한 기능만 나눠서 설계한다.DIP - 의존 역전 원칙 (Dependency Inversion Principle)구체적인 구현보다 인터페이스에 의존하도록 만든다.그래야 서로 유연하게 연결되고, 변경에 강한 구조를 만들 수 있다.
백엔드
・
워밍업클럽
![[워밍업 클럽 4기 - 백엔드] Day2 미션](https://cdn.inflearn.com/public/files/blogs/2324f403-559a-4f71-b438-5ee173276f0c/KakaoTalk_20250527_195638166.png?w=260)
2025. 05. 28.
0
[워밍업 클럽 4기 - 백엔드] Day2 미션
[인프런 워밍업 클럽 스터디 4기 - 백엔드]강의 출처 : Readable Code: 읽기 좋은 코드를 작성하는 사고법Day2 미션 : 추상과 구체의 예시 3-5문장으로 작성하기 추상 :하늘에서 비가 내린다.구체 :태양에 의해 지표면의 물이 수증기가 된다.수증기가 상승하면서 온도가 낮아지고, 물방울로 응결한다.응결된 물방울이 구름을 형성한다.구름 속의 물방울이 충분히 커지면 중력에 의해 지상으로 떨어지며 빗방울이 된다.이 빗방울은 대기를 뚫고 떨어져 땅에 닿는다.
백엔드
・
워밍업클럽




