우아한테크코스/미션 기록

[레벨1] 사다리 타기 1단계 - 사다리 생성

d02 2023. 4. 7. 14:13

 

기능 요구사항

  • 사다리 게임에 참여하는 사람에 이름을 최대5글자까지 부여할 수 있다. 사다리를 출력할 때 사람 이름도 같이 출력한다.
  • 사람 이름은 쉼표(,)를 기준으로 구분한다.
  • 사람 이름을 5자 기준으로 출력하기 때문에 사다리 폭도 넓어져야 한다.
  • 사다리 타기가 정상적으로 동작하려면 라인이 겹치지 않도록 해야 한다.
    • |-----|-----| 모양과 같이 가로 라인이 겹치는 경우 어느 방향으로 이동할지 결정할 수 없다.

 

구현하며 고민한 내용

1단계에서 주어진 요구사항 기본 구현을 목표로 TDD 방식으로 코딩하는 데 집중해서 진행해보았다.
페어 프로그래밍 규칙도 더 빠른 호흡으로 정해두니, TDD에 더 집중할 수 있었다.
대신, 처음부터 끝까지 TDD로 하고 클래스 설계에 시간을 많이 두지 않아서
코드 리뷰 반영 때에는 전체적인 설계 검토가 필요하기도 했다.

  • TDD 사이클
    • 기능 단위로 테스트 작성 → 실패 → 테스트 성공 → 기능 구현되면 커밋
  • 페어 프로그래밍 규칙
    • 5분마다 드라이버/내비게이터 교체
    • 고민할 거리가 생기거나 알고리즘 어려움 등 생기면 타이머 멈추고 고민 시간 가지기
  • 인터페이스와 구현체를 정의하는 기준
    • 어떤 것이 표준이고, 어떤 것이 세부 구현 내용인지 판단하자.
      • 리팩터링 전: RandomGenerator 라는 인터페이스 와 그에 대한 구현체를 정의했다.
      • 리팩터링 후: 랜덤을 사용하는 로직은 세부 구현 내용이고, StepPoint를 생성하는 것이 표준(공통 기능)이므로
        StepPointGenerator 라는 인터페이스와 그에 대한 구현체인 RandomStepPointGenerator를 정의했다.
  • 도메인 정보를 출력에 용이한 자료구조, 형식으로 바꾸는 것도 뷰를 위한 로직인가?
코드리뷰 피드백:
그렇다. 도메인이 뷰를 위한 로직을 가지면, 뷰가 바뀔 때마다 도메인의 코드도 변경되어야 하므로 OCP 원칙이 깨진다.
만약 도메인의 일부분을 더 정제된 형태로 뷰에 던지고 싶다면, 그 책임은 컨트롤러에게 주면 된다.

 

코드리뷰에서 배운 것들

  • "1차 피드백 외에 스스로 개선 포인트를 찾아서 더 나은 코드를 작성해 주신 것 같다" 는 평을 들어서 기분이 좋았다..!
    • 그래서 이후에도 리뷰를 받으면 README.md에 리팩터링 목록을 작성하며 내가 생각하기에 수정하고 싶은 항목도 추가하며 진행했다.
  • 생성자가 단순히 필드를 초기화하지 않고 복잡한 로직을 가지면 어떤 단점이 있을까?
    생성 로직을 생성자에 가두어 무조건 그 로직을 실행하도록 제어해야 한다고만 생각하고 있었는데, 리뷰어님이 던져주신 질문 덕분에 다시 한 번 고민해볼 수 있었다.
    1. 다른 개발자 입장에서는 해당 객체가 생성될 때 어떤 로직이 수행되는지 알 수 없다.
    2. 생성자는 다른 메서드명을 가질 수 없으므로 내부 실행 로직에 대한 파악이 더욱 어렵다.
    3. 생성자 메서드가 단순 필드 초기화 외에 여러 가지 일을 하게 된다.
      따라서 이와 같이 객체 생성 로직이 복잡해지는 경우, 정적 팩토리 메서드를 사용하기로 하였다.
  • Unmodifiable 방식으로 리스트를 반환하면, 처음 API를 사용하는 동료 개발자 입장에서 어떠한 단점이 있을까?
    1. unmodifiableList로 반환받더라도, 원본 객체의 변화에 영향을 받기 때문에 해당 반환값의 변화를 예측할 수 없다.
    2. 해당 반환값에 리스트를 수정하는 메서드(set, add, remove ..)를 호출했을 때 발생하는 예외가 RuntimeException이기 때문에 컴파일 시점에서는 확인이 되지 않는다. (해당 API에 대해 모르면 예외 발생을 예상할 수 없어 당황할 수 있다.)
      => 이런 문제를 방지하기 위해서는 unmodifiableList 대신 방어적 복사를 사용하자!
반응형