워밍업 클럽 4기 백엔드 - 2주 차 발자국

워밍업 클럽 4기 백엔드 - 2주 차 발자국

👣2주 차 발자국

 

강의 요약


섹션 6. 코드 다듬기

 

좋은 주석 - 주석의 양면성

  • 주석이 많으면 ?

    • 추상화가 덜 되고 가독성이 좋지 않은 코드 일 가능성이 높다.

  • 그렇다면, 주석을 써야하는 경우는?

    • 히스토리를 알 수 없을 경우, 주석으로 상세히 설명

 

변수와 메서드 나열 순서

  • 변수

    • 사용하는 순서대로 나열

  • 객체의 public/private 메서드

    • public 은 상단, private 은 하단 순으로 나열. public은 중요도에 따라 다시 나열.

      • public - 상태 변경 > 판별 > 조회

      • private - 출현한 순서대로

 

패키지 나누기

  • 적당한 수준으로 잘 나누어야 한다. (모호한 표현이긴 한데, 추상화 하는 개념 단위로 나누어야 되는 느낌)

  • 협업의 경우, 대규모 패키지 변경은 협의 후 진행

    • 패키지 이동으로 충돌 가능성이 존재

 

기능 유지보수하기

정렬 단축키, linting, style - sonarlint, editorconfig

 

섹션 7. 리팩토링 연습

 

메서드 추출로 추상화 레벨 맞추기

 

Optional

  • NPE 방지

  • 메서드 파라미터에 Optional 사용은 안티패턴

  • orElse()orElseGet()orElseThrow() 각각의 차이

 

객체에 메시지 보내기

  • 객체의 값을 꺼내서 사용하는 것이 아니라 존중하고 메시지를 보내야 한다.

 

객체의 책임과 응집도

  • 구현에 초점을 맞춘 추상화 VS 도메인 개념에 초점을 맞춘 추상화

     

  • 구현에만 초점을 맞춘 경우, 해당 구현체가 거대해 질 수 있다.

    • ( ex. file에서 읽는 것에 초점을 맞추는 것이 아니라, 어떤 데이터를 읽는 것인가 에 초점을 맞춰야 한다. )

  • 헥사고날 아키텍처 (포트, 어댑터) 의 기본 개념

 

섹션 8. 기억하면 좋은 조언들

 

능동적 읽기

  • 리팩토링하면서 읽기

     

  • 도메인 지식을 늘려야 함

 

오버 엔지니어링

  • 필요한 적정 수준보다 더 높은 수준의 엔지니어링

  • 구현체가 하나인 인터페이스

  • 너무 이른 추상화

 

은탄환은 없다

  • 만능인 것은 없다.

     

  • 소프트웨어 품질 VS 빠른 결과물

    • 추후의 리팩터링을 고려한 코드 작성 능력이 필요

  • 적정 기술의 범위 내에서 사용되어야 한다.

     

    • 결국 연습을 통한 적정 수준, 적정 시점을 깨달아야 함.

 

강의 - Readable Code: 읽기 좋은 코드를 작성하는 사고법

 


 

섹션 3. 단위 테스트

 

단위 테스트

  • 작은 코드(클래스 또는 메서드) 단위를 독립적으로 검증하는 테스트

  • 검증 속도가 빠르고, 안정적

 

수동 테스트, 자동화 테스트

  • 사람이 검증하는 수동 테스트

    • System.out.println 으로 직접 확인하는 방법

  • 기계가 검증하는 자동화 테스트

 

Junit5, AssertJ

  • Junit5 : 단위 테스트를 위한 테스트 프레임워크

  • AssertJ : 테스트 코드 작성을 원할하게 돕는 테스트 라이브러리 - 풍부한 API 메서드 체이닝 지원

 

해피 케이스, 예외 케이스

  • 예외 케이스 : 암묵적 혹은 드러나지 않은 요구사항에서 발견

 

테스트하기 어려운 영역 분리

  • 테스트하기 어려운 영역

    • 관측할 때마다 다른 값에 의존 - ex)

      현재 날짜/시간, random, 전역 변수/함수, 사용자 입력

    • 외부 세계에 영향을 주는 경우 - ex) 표준 출력, 메시지 발송, DB

     

  • 테스트하기 쉬운 영역 (순수 함수)

    • 같은 입력에는 항상 같은 결과

    • 외부 세상과 단절된 형태

 

lombok 사용 가이드

  • @Data, @Setter, @AllArgsConstructor 지양

  • 양방향 연관 관계의 @ToString 순환 참조 문제

 

섹션 4. TDD: Test Driven Development

 

TDD ?

프로덕션 코드보다 테스트 코드를 먼저 작성하여 테스트가 구현 과정을 주도하도록 하는 방법론

 

일반적인 개발 방법의 경우 (기능 -> 테스트 순서의 경우)

  • 테스트 누락 가능성

  • 해피 케이스만 검증할 가능성

  • 잘못된 구현을 늦게 발견할 가능성

     

     

TDD의 경우 (테스트 -> 기능 순서의 경우)

  • 테스트 가능한 코드로 구현할 수 있음

  • 엣지 케이스

  • 구현에 대한 빠른 피드백

     

  • 테스트 코드 보장 -> 과감한 리팩터링이 가능

 

레드 - 그린 - 리팩토링

  1. Red : 실패하는 테스트 작성

  2. Green : 테스트 통과 하는 최소한의 코딩

  3. Refactor : 구현 코드 개선 테스트 통과 유지

 

애자일 방법론

  • 반복적 개발(Iterative Development): 짧은 개발 주기(스프린트)를 반복하며 지속적으로 개선.

  • 유연성: 요구사항 변경을 수용할 수 있도록 유동적으로 진행.

  • 고객 참여: 개발 과정에서 지속적인 피드백을 반영하여 사용자 중심 개발 가능.

  • 자율적인 팀 구성: 개발팀이 자체적으로 의사 결정을 하며, 빠르게 문제를 해결함.

 

익스트림 프로그래밍

  • XP(Extreme Programming, 익스트림 프로그래밍)

    • 애자일 방법론 중 하나

    • 고객의 요구사항 변화에 빠르게 대응할 수 있도록 짧은 개발 반복 주기(Iteration)와 강한 협업

    • 실천 방법론으로 TDD를 제시 (켄트백)

스크럼, 칸반

  • 스크럼

    • 애자일 프레임워크로, 일정한 스프린트 동안 작업을 계획하고 진행하는 반복적이고 점진적인 개발 방식

  • 칸반

    • Workflow와 가시성을 중심으로 한 애자일 프레임워크

 

섹션 5. 테스트는 []다.

 

테스트 코드는 문서다.

  • 프로덕션 기능을 설명해주는 것이 테스트 코드 문서다.

  • 다양한 테스트 케이스를 통해 프로덕션 코드를 이해하는 시각과 관점을 보완할 수 있다.

  • 고민했던 내용(테스트 코드)을 팀 자산(소스 코드)으로 공유할 수 있다.

 

@DisplayName - 도메인 정책, 용어를 사용한 명확한 문장

  • 메서드명 만으로는 테스트 의도 파악이 어렵기 때문에 나옴 (Junit5)

     

  • 섬세한 DisplayName 예시

    • 특정 시간 이전에 주문을 생성하면 실패한다. ( X )

    • 영업 시작 시간 이전에는 주문을 생성할 수 없다. ( O )

       

  • 도메인 용어를 사용하여 추상화된 내용을 담기

    • ex. 영업 시작 시간

  • 테스트의 현상을 중점으로 기술하지 말 것

    • '실패한다' 와 같은 것은 검증과 무관

 

Given / When / Then - 주어진 환경, 행동, 상태 변화

  • Given : 시나리오 진행에 필요한 모든 준비 과정

  • When : 시나리오 행동 진행

  • Then : 시나리오 진행에 대한 결과 명시, 검증

 

TDD vs BDD

  • BDD

    • TDD에서 파생된 개발 방법 (TDD와 비교해보자)

    • 시나리오 기반한 테스트 케이스 자체에 집중하여 테스트한다.

 

Junit vs Spock

  • Spock은 Groovy언어로 BDD 패턴을 적용함

 

언어가 사고를 제한한다.

  • 명확하지 못한 테스트 코드는 사고를 제한할 수 있다.

     

 

강의 - Practical Testing: 실용적인 테스트 가이드

 

강의 회고

완강 후에 느낀 것은 '결국엔 많이 해봐야 익숙해지겠다.' 였다. 텍스트로 정리한 내용들을 기억 하고 있지만 정작 미션을 했을 때를 돌이켜 보면 손이 움직이지 않는다. 영어를 배웠지만 원어민 앞에서 얼어붙는 느낌이랄까?

그래도 강의를 통해 추상화 하는 과정을 따라해보고 지향해하 하는 점과 지양해야 하는 점의 방향성을 알게 되었기 때문에 좋았다. 강의의 실습내용을 반복하다보면, 언젠간 나도 내 코드에 만족할 수 있지 않을까?

 

TDD는 이전에 다른 강의를 통해 접한 내용을 복습하는 과정과 같아서 좋았다. TDD를 접했지만 아직까지도 TDD 방법론으로 프로젝트를 시작해 본 적이 없고, 테스트 라이브러리의 메서드도 쓰는 것만 쓰고... 반성을 한 시간이였다.

'왜? 배워야 하는가' 를 집중해서 배운 것 같은데 , 잘 알고 써야 의미가 있다는 느낌을 받았다. 알고 써야 의미있는 검증이 되는 것이지, 적당히 알고 쓰면 해피케이스만 작성하게 되고 의미없는 행위로 끝날 가능성이 높을 것이다.

 

미션 과정

강의를 통해 배운 내용들을 최대한 적용해 보려 했었다.

model패키지를 보면서 이전 강의의 지뢰찾기 리팩터링 보다는 좀더 추상화 되어 있는 상태라고 느꼈다.

컬렉션 추상화를 위해 일급컬렉션을 적용했고, StudyCafePassMachine에서 반복적으로 나오는 로직을 추상화 시켜 내용을 진행했다. 그리고 model 내부에 display 하는 내용들이 있어, io 패키지의 구현체들로 로직을 옮겼다.

 

미션 회고

접근 자체는 좋았다고 생각했는데, 구현이 막히고 시간에 쫓겨 강의를 보고 다시 리팩터링 했다. 어떻게 보면 답지를 배낀것이긴 하다. 기존의 model패키지에 있는 displa부분이 가장 고민이였는데, 출력과 금액 계산을 어떻게 나누는 가를 order라는 추상화를 통해 풀어가는 것을 보고 새로운 추상화를 만들어 가는 것을 과감히 시도해 봐야 겠다라고 느꼈다.
그리고 마지막에 file을 읽는 행위의 구현에 집중하는 것이 아니라, 어떤 데이터를 읽는 것인가에 집중해서 리팩터링을 하는 것이 기억에 남는다. 헥사고날 아키텍처의 기본 개념인데, 도서를 통해 이름을 본 적이 있는데 기억해 두었다가 필요할 때 학습을 통해 적용해 보면 좋을 것 같다.

 

댓글을 작성해보세요.

채널톡 아이콘