블로그
전체 72025. 06. 08.
1
워밍업 클럽 4기 DevOps - 2주차 발자국
🐾 발자국워밍업 클럽 4기 DevOps - 2주차를 듣고 작성하는 발자국입니다이번에 들은 강의 바로 가기 ⬇쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2📃 회고[2주차에 접어 들면서]원래는 하루에 무조건 하나씩 해야겠다는 생각을 가지고 있었는데 기말고사가 겹치다보니 점점 밀리기 시작했다 ,, 🥹그래도 중간에 연휴가 있어서 열심히 따라가다보니 일요일에 겨우겨우 완료할 수 있었다기말고사를 3주 동안 봐서 다음주랑 다다음주는 어떻게 하나 걱정되긴 하지만하루에 하나씩 열심히 해보자 아자잣 [2주차 강의를 들으며]1주차에 비교해서는 많이 가까워지긴 했지만 아직까지는 어색하다그래도 예전에 했던 기억들을 새록새록 기억해내고는 있지만 아직까지 미션도 제대로 풀기 어려운 상태 그래도 열심히 해서 쿠버네티스 마스터가 되는 그날까지 ,, 가보자고 ⚓ [️강의 정리 방법]강의를 들으면서 노션 정리노션 내용을 바탕으로 티스토리에 내용을 한 번 더 다듬어서 작성하는데 이렇게 강의를 정리하다보니깐 노션에 정리할 때 한 번, 티스토리에 정리할 때 두 번 내용을 정리할 수 있어서 머릿속에도 잘 들어오고 티스토리에 다듬어서 정리할 때 강의에서 궁금했던 내용들에 대해서 좀 더 찾아볼 수 있어서 좋다📺 강의 내용 정리저번주에는 쿠버네티스에 대해서 맛만 본 정도였지만 이번에는 각 기능들에 대해서 좀 더 알아보는 시간을 가졌다Prove, Configmap, Secret, PV/PVC, Deployment, Service, HPA 까지 아직 너무 많은 내용들이 들어오기도 했고 아직까지는 내용이 익숙하지 않아서 어렵지만앞으로 공부를 하다보면 더 익숙해지지 않을까라는 생각이 든다. 강의 내용 정리 블로그들 ⬇(5) Probe 이해하기(6) Configmap, Secret 이해하기(7) PV/PVC, Deployment, Service, HPA(8) Component 동작으로 이해하기
2025. 05. 31.
1
워밍업 클럽 4기 DevOps - 1주차 발자국
🐾 발자국워밍업 클럽 4기 DevOps - 1주차를 듣고 작성하는 발자국입니다이번에 들은 강의 바로 가기 ⬇쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2📃 회고[워밍업 클럽 4기를 하게 된 이유]일단 저번에 워밍업 클럽 3기를 했을 때의 기억이 정말 좋았다.보통 강의를 사두고, 안듣는 경우가 많은데 (그렇게 쌓인 강의만 한가득 .. )강사님과 함께 날마다 정해진 강의를 듣고 중간중간 미션을 수행하면서 하나의 강의를 완성할 수 있는게 큰 메리트로 느껴졌다. 그래서 이번에는 항상 공부해야지 해야지 했던 쿠버네티스가 있길래 고민도 안하고 바로 신청 했다. 흐흐 [쿠버네티스를 공부해야겠다고 생각한 이유]이전 회사에서 기존 docker 에서 쿠버네티스로 이전하는 과정에 참여하고, 스터디도 진행했는데시간이 지나니깐 모두 까먹었고 그 당시에도 쿠버네티스를 완벽히 이해하지 못했다.그래서 언젠가는 쿠버네티스를 공부해야겠다고 생각했었다. [워밍업 클럽 1주차를 들으며 .. ]이번 워밍업 클럽에는 신기하게 미션 & 발자국외에도 따로 팀이 존재한다강사님께서 팀 신청을 하면 랜덤으로 팀을 만들어주시는데,,어쩌다보니 내가 리더가 되어버렸다 🥹리더가 된 이상 열심히 해볼 예정 !! 치킨을 받을 수 있도록 아자잣그리고 강의 섹션이 짧게 구성되어 있고, 강의력도 좋으셔서 재밌게 듣고 있다.📺 강의 내용 정리이번 1주차 강의에서는 쿠버네티스에 대해서 살짝 맛본 느낌이였다.아직까지는 세세하게 머릿속에 그려지지는 않지만, 쿠버네티스가 이렇게 동작하는 구나 정도를 알아간것 같다.그 중 가장 기억에 남는 강의가 가장 처음에 배운 컨테이너 한방 정리이다.보통 쿠버네티스를 배우면 바로 Pod 가 뭐고, Service 가 어떤 역할을 하고로 접근할 때가 많은데리눅스 흐름으로 한 번 정리해서 보고, 쿠버네티스 흐름으로 정리해서 보니 쿠버네티스가 어떤 과정을 거쳐서 성장했고어떤 배경이 있는지를 대략적으로 파악할 수 있었다.곧 쿠버네티스에 대해서 조금 더 깊게 배울텐데 그때 지금 배운게 어떻게 설명될지 궁금하다 강의 내용 정리 블로그들 ⬇(1) 컨테이너 한방 정리 - Linux, Container, Container Orchestration, Kernel, kubelet(2) 쿠버네티스 무게감 있게 설치하기(3) 실무에서 느껴 본 쿠버네티스가 정말 편한 이유(4) Object 그려보며 이해하기[미션1] 쿠버네티스 설치 구간별 상태 확인
데브옵스 · 인프라
2025. 03. 31.
0
워밍업 클럽 3기 BE 클린코드&테스트 - 4주차 발자국
🐾 발자국워밍업 클럽 3기 BE 클린코드 & 테스트 - 4주차를 듣고 작성하는 발자국입니다이번에 들은 강의 바로 가기 ⬇Practical Testing: 실용적인 테스트 가이드📃 회고드디어 워밍업 클럽 3기가 끝나는 4주차가 다가왔습니다 🥹시간이 정말 빠르네요 ,, 처음 시작할 때는 강의 커리큘럼을 제때제때 들어야지 했는데 한 번 밀리니깐 진짜 한도 끝도 없이 밀리더군요 그래도 완강한 것에 의의를 두기로 했습니다 ☺📺 강의 내용 정리섹션 7 Mock 을 마주하는 자세외부 서비스가 있을 때 테스트하기 위해서 항상 호출할 수 없으니 이런 경우 Mocking 을 사용@MockitoBean private MailSendClient mailSendClient;Mockito.when(mailSendClient.sendEmail(any(String.class), any(String.class), any(String.class), any(String.class))) .thenReturn(true);위처럼 MailSendClient 를 Mock 처리해주고, 무조건 true 가 리턴하도록 Mocking 처리를 해줄 수 있다.Test DoubleDummy : 아무것도 하지 않는 깡통 객체Fake : 단순한 형태로 동일한 기능은 수행하나, 프로덕션에서 쓰기에는 부족한 객체Stub : 테스트에서 요청한 것에 대해 미리 준비한 결과를 제공하는 객체 그 외에는 응답하지 않는다.Spy : Stub 이면서 호출된 내용을 기록하여 보여줄 수 있는 객체, 일부는 실제 객체처럼 동작시키고 일부만 Stubbing 할 수 있다.Mock : 행위에 대한 기대를 명세하고, 그에 따라 동작하도록 만들어진 객체BDDMockito 를 사용하면 mockito.when 을 한 번 더 감싸 이름만 변경해서 given 으로 사용 가능 섹션 8 더 나은 테스트를 작성하기 위한 구체적 조언한 문단에 한 주제의 테스트만 작성하자제어할 수 없는 변수보다는 고정된 날짜와 고정된 값을 사용하자테스트를 이해하기 위해서 논리구조가 들어가는 구조는 사용하지 말자테스트 간 순서가 없어야하고 독립성을 보장해야 한다테스트가 독립될 수 있도록 구성하자 값이나 환경에 대해서 데이터를 바꿔서 여러번 실행하고 싶을 때 @ParameterizedTest 사용시나리오를 작성하고 싶다면 @DynamicTest 사용각 테스트 파일이 실행될 때마다 Spring Boot 서버가 실행되기 때문에 동일한 환경에서 테스트 코드가 구현될 수 있도록 관리필요private 메서드의 테스트가 필요하다면 객체를 분리할 시점인지 의문을 던져보기테스트에서 필요한 메소드를 만들어돈 되지만 보수적으로 접근하자. 섹션 9 Appendix 학습 테스트 : 잘 모르는 기능, 라이브러리, 프레임워크를 학습하기 위해서 작성하는 테스트Spring REST Docs :테스트 코드를 통해 API 문서 자동화하는 도구 ✔ 미션DAY 16 - Layered Architecture 구조의 레이어별 특징Persistence Layer DB 와의 상호작용을 담당하며, 데이터에 직접적으로 접근하는 계층테스트 방법데이터베이스에 CRUD 가 제대로 수행되는지 확인비즈니스로직이 들어가는게 아니라 데이터에 집중실제 데이터베이스를 사용하여 통합 테스트를 진행 Business Layer 비즈니스 로직을 담당하며, 실제 핵심적인 작업을 수행테스트 방법비즈니스 로직에서 발생할 수 있는 예외 상황을 처리하는 테스트를 집중적으로 작성비즈니스 로직 자체의 정확성을 확인하고 다양한 입력에 대한 예외 케이스 를 포함한 정상 동작 검증 Presentation Layer 외부 요청을 받는 계층으로 사용자 인터페이스나 외부 API와의 상호작용을 담당테스트 방법하단의 레이어는 모킹처리하여 실제 구현이 아닌 가짜 구현으로 테스트 진행사용자가 입력한 파라미터가 유효한지, 잘못된 값이 들어오지 않았는지 유효성 검사 케이스를 포함해야 한다 DAY 18 - @Mock워밍업 클럽 3기 BE 클린코드&테스트 - DAY18 미션
2025. 03. 31.
0
워밍업 클럽 3기 BE 클린코드&테스트 - DAY18 미션
🐾 DAY18 미션워밍업 클럽 3기 BE 클린코드 & 테스트 에서 하는 DAY18 미션입니다.Practical Testing: 실용적인 테스트 가이드✔ 미션 내용1. @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 의 차이를 한번 정리해 봅시다. 2. 아래 3개의 테스트가 있습니다. 내용을 살펴보고, 각 항목을 @BeforeEach, given절, when절에 배치한다면 어떻게 배치하고 싶으신가요? (@BeforeEach에 올라간 내용은 공통 항목으로 합칠 수 있습니다. ex. 1-1과 2-1을 하나로 합쳐서 @BeforeEach에 배치)1. @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 의 차이를 한번 정리해 봅시다. @Mock : 단위 테스트에서 가짜 객체를 만듬실제 객체를 생성하지 않고, when().thenReturn() 으로 원하는 동작 지정가능Spring 컨텍스트와 무관하게 사용가능@MockBean : 통합 테스트에서 특정 빈을 가짜로 만듬통합 테스트환경에서 Spring 컨텍스트 내에서 동작Spring 컨텍스트와 함께 사용 @Spy : 특정 메서드만 Mocking실제 객체를 생성하지만, 일부 메서드만 mocking 가능@SpyBean : @Spy 의 확장 버전 기존 빈을 Spy 로 감싸서 사용 가능@InjectionMocks : Mock객체들을 자동으로 주입하여 실제 객체를 생성@Mock, @Spy 로 생성된 객체들을 의존성으로 주입해 실제 객체를 구성2. 아래 3개의 테스트가 있습니다. 내용을 살펴보고, 각 항목을 @BeforeEach, given절, when절에 배치한다면 어떻게 배치하고 싶으신가요? (@BeforeEach에 올라간 내용은 공통 항목으로 합칠 수 있습니다. ex. 1-1과 2-1을 하나로 합쳐서 @BeforeEach에 배치)@BeforeEach void setUp() { 1-1/2-1. 사용자 생성에 필요한 내용 준비 1-3/2-3. 게시물 생성에 필요한 내용 준비 1-2/2-2/2-4. 사용자 생성 1-4. 게시물 생성 3-1. 사용자1 생성에 필요한 내용 준비 3-3. 사용자2 생성에 필요한 내용 준비 3-5. 사용자1의 게시물 생성에 필요한 내용 준비 3-2. 사용자1 생성 3-4. 사용자2 생성 3-6. 사용자1의 게시물 생성 } @DisplayName("사용자가 댓글을 작성할 수 있다.") @Test void writeComment() { // given 1-5. 댓글 생성에 필요한 내용 준비 // when 1-6. 댓글 생성 // then 검증 } @DisplayName("사용자가 댓글을 수정할 수 있다.") @Test void updateComment() { // given 2-5. 댓글 생성에 필요한 내용 준비 // when 2-6. 댓글 생성 2-7. 댓글 수정 // then 검증 } @DisplayName("자신이 작성한 댓글이 아니면 수정할 수 없다.") @Test void cannotUpdateCommentWhenUserIsNotWriter() { // given 3-7. 사용자1의 댓글 생성에 필요한 내용 준비 // when 3-8. 사용자1의 댓글 생성 3-9. 사용자2가 사용자1의 댓글 수정 시도 // then 검증 }게시판 게시물에 달리는 댓글을 담당하는 Service Test 이기 때문에 setUp 에서 게시판 댓글과 관련 없이 만들어야 하는 내용들을 생성해주고, 각각의 테스트 메서드에서는 댓글과 관련된 내용들만 테스트 수행할 수 있도록
2025. 03. 31.
0
워밍업 클럽 3기 BE 클린코드&테스트 - 3주차 발자국
🐾 발자국워밍업 클럽 3기 BE 클린코드 & 테스트 - 3주차를 듣고 작성하는 발자국입니다이번에 들은 강의 바로 가기 ⬇Practical Testing: 실용적인 테스트 가이드📃 회고[워밍업 클럽 3주차를 들으며 .. ]3주차 발자국을 제출하는 걸 깜박한 바보가 있다 ? 🤔바로 접니다 ...... 바보 ......강의를 모두 듣고 해야하는게 없는 줄 알고 주말동안 디스코드에 들어가고 있지 않다가월요일날 발자국을 안썼다는 사실이 갑자기 떠올랐습니다워밍업클럽 완주 조건은 발자국을 모두 작성하는 것이다보니깐 완주는 못하겠다 생각하고 있었는데 완주 유예기간이 생겨서 후다닥 3주차 발자국을 작성하게 되었답니다 🙌3주차는 Day11 미션과 Persistence Layer / Business Layer / Presentation Layer 로 나눠서 각 영역별로본격적인 테스트코드에 대해서 배우는 주였습니다.사실 실무에서 테스트코드를 짜야지 짜야지 말만 하고 못짠 이유가 테스트가 어렵다라는 편견때문이였는데강의를 듣고 테스트 코드를 어떻게 짜야하는지 감이 잡히고 나니깐 테스트 코드가 겁먹을 게 아니구나 라는 생각이 들었습니다.📺 강의 내용 정리섹션6 레이어 아키텍처와 테스트사용자 요청을 세 개의 레이어 (Presentation Layer / Business Layer / Persistence Layer ) 로 나누어서 처리하자레이어를 구분하는 이유는 관심사의 분리를 위해서레이어에 따라 관심사를 분리하면 책임을 나누고 유지보수하기 용이해진다.A + B 면 AB, BA, C 중 무엇이 될지 혹은 이 외의 것이 될 지 예측하기 정말 어렵다. 그렇기 때문에 통합 테스트가 필요하다.통합테스트는 여러 모듈이 협력하는 기능을 통합적으로 검증하는 테스트 섹션6 Persistence LayerDB 와 통신해서 데이터를 저장하는 계층 (Repository)@ActiveProfiles("test") @DataJpaTest // Jpa 관련 빈들만 주입해준다 class ProductRepositoryTest { @Autowired private ProductRepository productRepository; @DisplayName("원하는 판매상태를 가진 상품들을 조회한다.") @Test void findAllBySellingStatusIn() { // given Product product1 = Product.builder() .productNumber("001") .type(HANDMADE) .sellingStatus(SELLING) .name("아메리카노") .price(4000) .build(); Product product2 = Product.builder() .productNumber("002") .type(HANDMADE) .sellingStatus(HOLD) .name("카페라떼") .price(4500) .build(); Product product3 = Product.builder() .productNumber("003") .type(HANDMADE) .sellingStatus(STOP_SELLING) .name("팥빙수") .price(7000) .build(); productRepository.saveAll(List.of(product1, product2, product3)); // when List products = productRepository.findAllBySellingStatusIn(List.of(SELLING, HOLD)); //then assertThat(products).hasSize(2) .extracting("productNumber", "name", "sellingStatus") .containsExactlyInAnyOrder( tuple("001", "아메리카노", SELLING), tuple("002", "카페라떼", HOLD) ); } }PersistenceLayer 의 코드 예시@ActiveProfiles 로 실행된 환경을 지정예시 데이터들을 저장해주고 (product1, product2, product3) 해당 데이터들이 잘 저장되었는지 확인hasSize : size 가 일치하는지 확인하는 메서드extracting : 가져올 컬럼을 설정containsExactlyInAnyOrder : 값들이 일치하는지 확인 섹션6 Business Layer비즈니스 로직을 구현하는 계층 (Service)Persistence Layer 와의 상호작용으로 로직을 전개@DisplayName("주문번호 리스트를 받아 주문을 생성한다.") @Test void createOrder() { // given LocalDateTime registeredDateTime = LocalDateTime.now(); Product product1 = createProduct(HANDMADE, "001", 1000); Product product2 = createProduct(HANDMADE, "002", 3000); Product product3 = createProduct(HANDMADE, "003", 5000); productRepository.saveAll(List.of(product1, product2, product3)); OrderCreateRequest request = OrderCreateRequest.builder() .productNumbers(List.of("001", "002")) .build(); // when OrderResponse orderResponse = orderService.createOrder(request, registeredDateTime); //then assertThat(orderResponse.getId()).isNotNull(); assertThat(orderResponse) .extracting("registeredDateTime", "totalPrice") .contains(registeredDateTime, 4000); assertThat(orderResponse.getProducts()).hasSize(2) .extracting("productNumber", "price") .containsExactlyInAnyOrder( tuple("001", 1000), tuple("002", 3000) ); }Service 내의 메서드가 정상적으로 작동하는지 검증 섹션6 Presentation Layer외부 세계의 요청을 가장 먼저 받는 계층 파라미터에 대한 최소한 검증을 수행✔ 미션DAY11 미션 - 단위 테스트 작성하기 내용3개 이상의 서로 다른 클래스 & 총 7개 이상의 테스트 작성무엇을 테스트하고자 했는지를 잘 나타낸 @DisplayName 작성BDD 스타일 따르기 https://inf.run/CBsAt
2025. 03. 15.
0
워밍업 클럽 3기 BE 클린코드&테스트 - 2주차 발자국
🐾 발자국워밍업 클럽 3기 BE 클린코드 & 테스트 - 2주차를 듣고 작성하는 발자국입니다이번에 들은 강의 바로 가기 ⬇Readable Code: 읽기 좋은 코드를 작성하는 사고법 Practical Testing: 실용적인 테스트 가이드📃 회고 [워밍업 클럽 2주차를 들으며 .. ]이번주는 Reable Code 가 끝나고 Practical Testing 으로 넘어가는 주이기도 하고중간에 미션으로 클린코드 리팩토링 실습이 있어서 꽤나 의미있는 학습을 한 주였습니다 !!사실 코드리뷰를 신청하기 전까지만 해도 ,,, 코드가 완벽하다고 생각하지 않아서 낼까말까 진짜 고민했는데요이번주 중간점검을 해보고나니깐 코드리뷰를 신청하기 정말 잘했다는 생각이 들었습니다 ☺다른 분들이 짠 코드를 보고 많이 배우기도 했고, 박우빈 코치님이 주신 제 코드에 대한 피드백에서도 많이 배웠네용Reable Code 강의는 끝났지만, 앞으로도 클린코드에 대한 관심은 쭈욱 이어갈 생각입니다👍 2주차에서 잘한 점코드리뷰 신청하기이번주 모든 강의를 들은 것 !! 👎 2주차에서 못한 점갑자기 일이 바빠져서 코드를 더욱 심도있게 생각하고 짜지 못한 것 🥅 3주차의 목표다음주에 있는 미션에는 조금 더 깊게 생각해서 미션을 잘 해내자 !!📺 강의 내용 정리[Reable Code]섹션6 코드 다듬기주석의 양면성주석이 너무 많다는 것은 비즈니스 요구사항을 코드에 잘 못 녹였따는 이야기 만일, "의사 결정의 히스토리"를 도저히 코드로 알 수 없다면 코드로 상세하게 설명해야 한다변수와 메서드의 나열 순서 변수는 사용하는 순서대로 나열한다 (인지적 경제성)공개메서드는 기준을 가지고 배치하고, 비공개 메서드는 공개 메서드에 언급된 순서대로 배치하는 것이 좋다패키지 나누기패키지는 문맥으로써의 정보를 제공한다패키지를 쪼개지 않으면 관리가 어렵고 너무 잘게 쪼개도 관리가 어렵다처음만들 때부터 잘 고민해서 패키지를 나누자IDE의 도움 받기 코드 스타일에 신경을 써야 가독성을 높일 수 있다 섹션8 기억하면 좋은 조언들능동적 읽기복잡하거나 엉망인 코드를 일고 이해할 때 리팩토링하면서 읽기 우리의 핵심 목표는 도메인 지식을 늘리는 것오버 엔지니어링 필요한 적정 수준보다 더 높은 수준의 엔지니어링을 하는 것은 불필요하다꼭 필요한 곳에 알맞게 적용하자 은탄환은 없다실무는 지속가능한 소프트웨어의 품질과 기술 부채를 안고 가는 빠른 결과물의 줄다리기모든 기술과 방법론은 적정 기수의 범위 내에서 사용되어야 한다 [Pratical Testing]섹션2. 테스트는 왜 필요할까? 사람이 테스트하다보면 다양한 사이드이펙트가 생길 수 있다테스트 코드를 통해서 빠른 피드백 / 자동화 / 안정감을 얻을 수 있다테스트는 귀찮지만 해야 한다 섹션3. 단위테스트JUnit5로 테스트하기단위테스트 : 작은 코드 단위를 독립적으로 검증하는 테스트Junit5 : 단위 테스트를 위한 테스트 프레임워크AssertJ : 테스트 코드 작성을 원활하게 돕는 테스트 라이브러리 테스트 케이스 세분화하기암묵적이거나 아직 드러나지 않은 요구사항이 있는가?해피 케이크 & 예외 케이스에 대한 고민이 필요 테스트하기 어려운 영역을 분리하기테스트가 어려운 영역을 외부로 분리기본적으로는 어려운 영역을 분리해서 외부로 분리를 하면 할 수록 테스트할 수 있는 영역이 많아진다 섹션4. TDD프로덕션 코드보다 테스트 코드를 먼저 작성하여 테스트가 구현과정을 주도하도록 하는 방법론구현부 없이 테스트 먼저 작성 (실패) > 테스트를 통과하도록 구현부를 엉터리로 작성 (통과) > 리팩토링 (통과) 섹션5. 테스트는 []다테스트는 문서다프로덕션 기능을 설명하는 테스트 모드 문서DisplayName을 섬세하게명사의 나열보다 문장으로~테스트를 지양하기테스트 행위에 대한 결과까지 기술하기도메인 용어를 사용하여 한층 추상화된 내용을 담기 BDD 스타일로 작성하기TDD 에서 파생된 개발방법Given / When / Then✔ 미션DAY 7 미션 - 클린코드 리팩토링 실습코드 : https://github.com/soyeon207/readable-code/pull/1 시스템 요구사항사용자는 시간권, 주단위 이용권, 1인 고정석 중 선택할 수 있다시간권 : 2, 4, 6, 8, 10, 12시간주권 : 1, 2, 3, 4, 12주고정석 : 4주, 12주추가금액을 내면 사물함도 사용할 수 있는데, 고정석인 경우만 선택 가능하다선택한 이용권, 사물함 여부에 따른 최종 금액을 계산해 준다.오픈 이벤트로 2주권 이상 10%, 12주권 15% 할인을 진행중이다리팩토링 내용사물함을 의미하는 Locker 와 이용권을 의미하는 CafePass 개념을 도출사물함 이용권을 찾고, 사물함에 대한 총 금액을 출력하는 코드는 사물함 관련 로직임으로 Locker 클래스로 이관이용권별로 일어나는 비즈니스 로직은 이용권 도메인에 관련된 로직임으로 CafePass 클래스로 이관구체적인 코드들의 경우 메서드로 추출해 의미를 더욱 명확하게 전달"1".equals(userInput) 의 경우 doesUserChooseToHourlyType(userInput) 메서드로 추출System.out.println(); 와 같이 반복되어 나타나는 코드의 경우 lineBreak(); 라는 메서드로 추출
2025. 03. 09.
0
워밍업 클럽 3기 BE 클린코드&테스트 - 1주차 발자국
🐾 발자국워밍업 클럽 3기 BE 클린코드 & 테스트 - 1주차를 듣고 작성하는 발자국입니다이번에 들은 강의 바로 가기 ⬇Readable Code: 읽기 좋은 코드를 작성하는 사고법 📃 회고[워밍업 클럽을 듣게 된 이유]대학교 개강을 앞두고 있던 와중 ,,, 개강하면 열심히 살아야겠다는 다짐을 하던 와중인프런 워밍업 클럽을 모집한다는 메일을 발견하게 되었습니다지금까지 인프런에서 강의를 완강하려면 거의 3~4개월이 필요했던 저는 이번 기회를 통해서 공부 습관을 다잡고 하루를 알차게 살아보자라는 생각에강의를 결제하고 워밍업 클럽을 신청하게 되었습니다. [워밍업 클럽 1주차를 들으며 .. ]박우빈 코치님이 짜주신 커리큘럼을 따라서 강의를 듣자는 목표를 세웠습니다.OT 를 참가했을 때 우리가 진행하는 커리큘럼이 굉장히 빡셀 수도 있다라는코치님의 말을 들으면서 내가 할 수 있을까 ,,,, 🧐 라는 생각도 잠시실제로 들어보니깐 힘들긴 했지만 그래도 못들을 정도의 학습량은 아니더라고요 !✔ 커리큘럼이 짜여져 있고✔ 강의를 듣는 사람들이 여러명이고✔ 미션을 통해 강의 내용을 중간중간 확인할 수 있고✔ 강의 내용이 좋아서더욱 열심히 들었습니다 !!이론으로 듣고 실제 코드를 고쳤을 때의 희열도 있었던 것 같아요 ㅎㅎ 👍 1주차에서 잘한 점 날마다 정해진 강의량을 들은 것미션을 빼먹지 않고 참여한 것 👎 1주차에서 못한 점강의를 듣고 난후 나만의 언어로 바꿔서 복습하지 않은 것 🥅 2주차의 목표강의를 모두 들은 후 나만의 언어로 정리해 내 걸로 만들기 !📺 강의 내용 정리섹션2 추상 (抽象)우리가 클린코드를 추구하는 이유 우리는 가독성을 위해서 클린 코드를 추구한다.가독성이 좋아지면 얻을 수 있는 것들이 많다. (이해가 잘되고, 유지보수하기 수월함)클린 코드를 추구하기 위해서 가장 중요한 주제가 바로 추상추상과 구체 중요한 정보는 가려내어 남기고, 덜 중요한 정보는 생략하여 버리는 것이 추상인간은 자연스럽게 추상화 능력을 가지고 있다'잘못된 추상화'는 굉장히 큰 사이드 이펙트를 가져오지만'적절한 추상화' 는 해당 도메인의 문맥 안에서 정말 중요한 핵심 개념만을 남겨서 표현함으로서 굉장히 큰 이점을 얻을 수 있다.이름 짓기이름을 짓는다는 건 추상적 사고를 기반으로 한다단수와 복수를 구분하기 / 이름 줄이지 않기 / 은어, 방어 사용하지 않기 / 좋은 코드를 보고 습득하기 메서드와 추상화잘 쓰여진 코드라면 한 메서드의 주제는 반드시 하나다.메서드의 이름은 구체적인 내용을 추상화해서 잘 나타내야 한다생략할 정보와 의미를 부여하고 드러낼 정보를 잘 구분해야 한다 메서드 선언부 반환타입 메서드명 ( 파라미터 ) 가 메서드 선언부반환타입, 메서드명, 파라미터에 추상화된 정보를 잘 담아야 한다추상화 레벨메서드로 추출한 경우 메서드 내부와 외부로 경계가 생긴다각각의 세계에서는 추상화 레벨이 동등해야 한다 섹션3 논리, 사고의 흐름뇌 메모리 적게 쓰기 최소한의 인지로 최대한의 효율을 내자뇌의 메모리에 적은 정보를 올릴수록 읽기 쉬운 코드가 된다Early returnif - else if - else 를 사용하는 경우 else 까지 오게 되면 If, else if 의 내용을 기억하고 있어야 한다이렇게 복잡한 코드를 사용하는 것이 아닌 조건문이 끝날 때마다 return 을 하게 되면 앞의 코드를 신경쓰지 않아도 된다사고의 depth 줄이기중첩 분기문, 중첩 반복문을 사용하면 사고의 depth 가 굉장히 깊어진다무조건 1 depth 로 만드는 것이 아니라 추상화를 통한 사고 과정의 depth 를 줄이는 것이 중요하다공백 라인을 대하는 자세공백 라인도 의미를 가진다복잡한 로직의 의미 단위를 나누어 보여줌으로써 읽는 사람에게 추가적인 정보를 전달할 수 있다부정어를 대하는 자세부정어구를 쓰지 않아도 되는 상황인지를 체크하고부정의 의미를 담은 다른 단어가 존재하는지 고민하거나 부정어구로 메서드명을 구성한다해피 케이스와 예외 처리사람은 해피 케이스에만 몰두하는 경향이 있지만 예외처리를 꼼꼼히 할수록 더욱 좋은 개발자가 된다예외가 발생할 가능성을 낮추고, 의도한 예외와 예상하지 못한 예외를 구분하자항상 NullPointException 을 방지하는 방향으로 개발해야 한다Optional 은 비싼 객체이기 때문에 꼭 필요한 상황에서 반환타입에 사용한다. 섹션 4 객체 지향 패러다임추상의 관점으로 바라보는 객체 지향 객체 지향 : 객체를 통해 객체간의 협력으로 프로그래밍 객체 : 추상화 된 [데이터 + 코드] 관심사를 분리해 관심사를 한 곳으로 모으면 유지보수에 도움이 된다객체 설계하기관심사가 퍼져 있는 코드에서 관심사를 한 곳으로 모다 객체로 분리해야 한다분리된 객체에서 공개 메서드를 통해서 기능을 제공한다객체의 책임이 나뉨에 따라 객체간의 협력이 강조된다새로운 객체를 만들때에는 1개의 관심사로 명확하게 책임이 정의되었는지 확인한다SRP (단일 책임 원칙)하나의 객체는 하나의 책임만 가져야 한다관심사를 분리해서 높은 응집도, 낮은 결합도OCP (개방-폐쇄 원칙)확장에는 열려있고, 수정에는 닫혀있어야 한다추상화와 다형성을 활용해 OCP 를 지킬 수 있다LSP (리스코프-치환 원칙)상속 구조에서 자식 클래스는 부모 클래스의 책임을 준수해야한다ISP (인터페이스 분리 원칙)클라이언트는 자신이 사용하지 않는 인터페이스에 의존해선 안된다DIP (의존성 역전 원칙)상위 수준의 모듈은 하위 수준의 모듈에 추상화로 의존해야 한다 섹션 5 객체 지향 적용하기상속과 조합상속보다는 조합을 사용해야 한다. 상속은 시멘트처럼 굳어지는 구조이기 때문에 수정이 어렵다Value Object 기본타입을 객체로 감싸서 의미를 부여하고 추상화하는 기법값으로 취급하기 위해서 불변성, 동등성, 유효성 검증 등을 보장해야 한다Entity 는 식별값으로 객체를 비교하지만, VO 는 내부의 모든 값이 같아야 같은 객체로 취급 ✔ 미션DAY2 미션 - 추상과 구체의 예시 미션내용 : "추상과 구체" 강의를 듣고, 생각나는 추상과 구체의 예시가 있다면 한번 3~5문장 정도로 적어봅시다. 미션 수행 내용추상스타벅스에서 음료를 테이크아웃한다구체스타벅스 앱에 접속한다주문할 매장을 선택한다픽업 옵션에서 To-go 를 선택한다슈크림라떼를 선택한 뒤, 원하는 옵션을 추가한다결제 방식을 선택한 후 결제를 완료한다매장에 도착해 주문 번호가 호출될 때까지 기다린다.슈크림라떼를 테이크아웃한다 DAY4미션1 - 코드 리팩토링미션 내용 : 아래 코드와 설명을 보고, [섹션 3. 논리, 사고의 흐름]에서 이야기하는 내용을 중심으로 읽기 좋은 코드로 리팩토링해 봅시다.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()) { showInfoLog("주문 항목이 없습니다."); return false; } if (order.isNotHaveCustomerInfo()) { showInfoLog("사용자 정보가 없습니다."); return false; } if (order.isNotValidPrice()) { showInfoLog("올바르지 않은 총 가격입니다."); return false; } return true; } private void showInfoLog(String msg) { log.info(msg); }Order 객체 내부에 isEmptyOrder, isNotHaveCustomerInfo, isNotValidPrice 메서드를 만들어서 Order 에 대한 행동을 Order 자체에서 제어할 수 있도록 구현isEmptyOrder : 주문이 비었는지 아닌지 확인isNotHaveCustomerInfo : 사용자 정보가 비었는지 확인isNotValidPrice : 올바르지 않은 총 가격인지 확인 DAY4미션2 - SOLID미션 내용 : SOLID에 대하여 자기만의 언어로 정리해 봅시다.미션 수행 S (단일책임원칙)각 객체가 하나의 명확한 관심사(책임)만을 가져야 한다책임을 발견해내는 것은 경험의 영역이기 때문에 객체를 설계할 때마다 현재 객체가 하나의 책임만 가지고 있는지 질문해야 한다ex) MinesweeperGame -> Minesweeper 랑 GameApplication 으로 분리O (개방-폐쇄원칙)확장에는 개방되어 있고, 수정에는 폐쇄되어야 한다새로운 요구사항이 발생되었을 때에도 기존 코드를 직접 수정하지 않고, 확장할 수 있는 방식으로 설계해야 한다ex) 결제 수단을 여러 개 추가해야 하는 경우L (리스코프 치환 원칙)상속구조에서 부모클래스를 자식클래스로 치환할 수 있어야 한다부모클래스에서 사용하는 기능을 자식클래스가 사용하지 않는다면 추가적인 코드 처리가 필요하게 되는데, 이런 경우 사이드 이펙트가 발생할 수 있다ex) Animal 클래스에 fly 메서드가 있는데 Animal 을 상속받는 동물이 사자인 경우I (인터페이스 분리 원칙)인터페이스의 단위를 잘게 쪼개 클라이언트가 사용하지 않는 기능을 사용하지 않도록 해야 한다인터페이스에 클라이언트가 사용하지 않는 기능이 포함되어 있으면 사용하지 않는데 추가적인 코드 작업을 해야하고, 클라이언트 입장에서는 해당 메소드의 의미를 모르게 된다ex) Animal 인터페이스에 fly() 랑 walk() 메서드가 있으면 Fly 인터페이스, Walk 인터페이스 로 분리D (의존성 역전 원칙)상위 수준 모듈은 하위 수준 모듈의 추상화에 의존해야 한다상위 수준 모듈이 하위 수준 모듈의 구체적인 코드를 알 필요가 없다. 추상화를 통해 어떤 기능을 제공하는지만 알려주고 내부적인 코드는 하위 수준 모듈들에서 작성할 수 있도록 해야 한다상위 수준 모듈인 음식점의 경우 하위 수준 모듈로 라면끓이는 법을 아는게 아니라 음식만드는 법이라는 추상화에 의존하면 여러 메뉴를 만들 수 있음
백엔드
・
워밍업클럽
・
워밍업클럽3기
・
클린코드&테스트