[우테코 8기 프리코스] 3주차 회고

코드싸개 김 씨·2025년 11월 4일
post-thumbnail

시작하기 전


이번 주 회고에도 시작하기 전에 저번 주에 세웠던 목표들을 확인해보고자 한다.

저번 주차에 세웠던 내 개인 목표는 이렇다.

  • 단위 테스트 작성하기
  • TDD 도입하기
  • 적절한 의존성 주입 활용하기
  • 정적 메서드 사용 줄여보기

단위 테스트 작성하기

-> 살짝 아쉬웠다. 의존성이 없는 모듈들의 단위 테스트는 잘 작성된 것 같았지만, 의존성이 어느 정도 존재하는 클래스들에 대한 단위 테스트의 작성은 미흡했던 것 같다.

(테스트 커버리지 확인을 처음해보는데, 뭔가 잘못 나오고 있는 것 같다. 이렇게까지 꼼꼼하게 테스트를 짜진 않았는데 좀 더 알아봐야겠다..)

TDD 도입하기

-> 생각보다 나쁘지 않았던 것 같다. 사실 TDD 도입을 진행하면서 모듈 단위 작업을 마치고 한번 겪었던 시행착오가 있는데, 이후 아래에서 후술하겠다.

(추가로 TDD 입문이나 방향 잡기가 어려우신 분들은 이 책을 추천드립니다. 저도 아직 다 못읽었지만 상당히 좋은 내용이 많습니다.)

최범균 님 - 테스트 주도 개발 시작하기
(https://product.kyobobook.co.kr/detail/S000001248962)

적절한 의존성 주입 활용하기

-> 저번 주에 비하면 훠어어얼씬 나아졌다. 적절한 수준의 의존성을 도입했다는 생각이 든다. 이것도 아래 설계 부분에서 후술하려 한다.

정적 메서드 사용 줄여보기

-> 이번에는 View 역할을 담당하는 클래스를 제외하고 최대한 static 키워드를 사용하지 않았다. 충분히 의미 있는 변화였다!

🚩과제 내용


3주차 과제 내용은 아래와 같았다.

추가로 2주차까지의 프로그래밍 요구사항 + 아래 사항이 추가되었다.

switch - case문을 제한하는 건 생각보다 꽤 부담되는 조건이었던 것 같다.

확실히, 2주차보다 고민할 사항들이 늘어난 느낌이 들었다.
그리고 제공되는 Lotto 클래스를 사용하라는 조건도 붙었다.


(사실 이 부분은 오히려 좋았다. 로또 도메인 설계에 대한 고민을 줄일 수 있었다.)

🧐 설계 중 시행착오


사실 2주차에 비해서 기능이 많아졌고, 특히

'에러 발생 시 프로그램 종료가 아닌 그 부분부터 다시 입력받는다.'

이 부분이 꽤 까다롭게 느껴졌다.

우선 고민하면서 노트에 대략적인 흐름을 끄적여보았다.

아래는 출력과 입력에 대한 구조를 보고, 대략적인 책임을 나눠보려했다.

처음에는 2개로 나누려다가, 당첨번호 입력을 한 번 더 나누어 세 파트로 나누었다.

사실 이렇게 설계했던게, REST API 구조를 생각하고 설계했는데 실제로 구현하게 된 결과물은 생각했던 요청 - 응답 구조랑은 살짝 달라진 것 같다.

🛠️ 설계


우선 이번에는 TDD를 적용하면서 각 모듈들 간의 의존성을 최소화하고 기능을 구현했다.
처음에는 모듈 간의 의존성이 없어 README 파일에 작성한 기능 목록과 예외 처리 내역을 바탕으로 실패 및 성공 테스트를 작성했다.

그러다, 최종적으로 로또 애플리케이션의 흐름을 담당하는 기능을 구현할 때 적잖아 당황했다. 내가 설계했던 부분만큼 잘 결합되지가 않아 중간중간 작성했던 모듈들의 기능을 수정하는 상황이 발생했다.

이때는 이미 제출 마감 시간은 약 8시간 남짓 남았었고..
급하게 테스트 코드를 작성할 시간도 없이 바로 기능 작성 및 구현을 하고 제출했다.
최종적으로 TDD를 반쯤 지킨 꼴이 되었다. 사실 조금 아쉬운 실패였다.


(다행히 예제 테스트는 통과하긴 한..)

각 입력에 따라
로또 생성 - LottoHandler
당첨번호 생성 - WinningNumberHandler
보너스 번호 생성 - BonusNumberHandler

위 클래스들을 기반으로 Validator 클래스와 Generator 클래스들을 의존성 주입하여 각 로직들을 구현했다.

각 입력 및 출력은 view 패키지 내부 클래스에 책임을 분배하고,

클래스마다 자주 이용되는 상수는 LottoConstant로 분리, 상금 관련된 상수는 WinningPrize 열거형으로 분리했다.

😎 미션 종료 후


이번 주차 공통 피드백이다. 확실히 TDD + 단위테스트 시도 자체는 새로운 도전이라 쉽지 않았는데, 그나마 위안이 되는 말씀이었다.

직접 구현을 진행하면서 느낀 건, 메서드 15줄은 생각보다 길었다.
무난하게 이를 지킬 수 있었다.

다만

'예외 상황에 대해 고민한다'

이 피드백도 1주차의 내 모습을 다시 돌아보게 했다. 설계 중 놓친 예외가 없었는지 깊게 고민하던 때가 잠시 떠올랐고, 무의미한 시간은 아니었구나 라는 안도감이 들었다.

그리고.. 아래는 가장 인상 깊었던 부분이다.

사실 시간이 없어서라는 핑계를 댓지만, 저런식으로 메시지를 반환하는 메서드가 있음에도 불구하고 급하게 Getter 메서드를 구현했던 내 자신을 반성하게 되었다.

public class WinningNumber {

    private final List<Integer> numbers;

    public WinningNumber(List<Integer> numbers) {
        validate(numbers);
        this.numbers = numbers;
    }
    
    // ~~~기능 중략~~~~
    
    public boolean contains(int number) {
        return numbers.contains(number);
    }

    public List<Integer> getNumbers() {
        return List.copyOf(numbers);
    }
 }

위쪽 contains() 메서드 같은 좋은 구조를 구현했음에도 안일하게 Getter 메서드를 작성한 게 떠올랐다.
(그래도 불변 리스트로 반환하겠다고 저렇게 구현한 게 웃기긴 하다.)

아래는 공유받은 링크이다.

getter를 사용하는 대신 객체에 메시지를 보내자
https://tecoble.techcourse.co.kr/post/2020-04-28-ask-instead-of-getter/

나중에 TDD가 깨진 가장 큰 원인이었던 것 같기도 하다.
(매우매우 찔리는 나)

아래 부분도 정말 인상 깊었다.
사실 private 메서드가 많을 수록 분리가 필요한 시점이라는 생각도 다시금 들었다.

메서드 시그니처를 수정하여 테스트하기 좋은 메서드로 만들기
https://tecoble.techcourse.co.kr/post/2020-05-07-appropriate_method_for_test_by_parameter/

👀 느낀 점


이번에 가장 크게 느꼈던 건 조금씩 TDD에 대한 감이 잡히기 시작했던 것 같다. 아직 많이 경험해본 것은 아니지만.. 잘 깎는다면 충분히 나와 잘 맞을 것 같다는 생각이 강하게 들었다.

3주차 과제를 진행하면서, 가장 아쉬웠던 부분이 TDD를 끝까지 지켜내지 못했다는 부분이 아무래도 이번 주차에 가장 기억에 남을 것 같다.

사실상 클래스 분리가 좀 더 잘게 나눠졌다면, 좀 더 쉽게 구현에 성공했을 것 같다는 생각도 들었다.

저번 주차의 내가 했던 생각인데 여전히 그대로인 것 같기도 하다.

✒️ 다음 주 목표


이 글을 적는 시점은, 이미 오픈 미션이 공개되고 난 후의 시점이다.

사실은 지금 이런 기분이다.

'어떤 걸 해서 미션에 내고, 나 스스로가 몰입할 수 있을 지?'

조금 큰 수영장 중앙에 던져진 기분이다.

일단 모르겠으니, 다음 주 목표는

  • 저번주보다 더 나은 내가 되기
  • 이전보다 더 깊이 몰입해보기
  • 미션으로 진행해볼 거리 찾아보기

이렇게 정했다.
사실 단순히 문제만 푸는 것보단, 정해진 답이 없는 이번 미션은 어쩌면 나한테는 또 한 번의 큰 기회일지도 모르겠다는 생각이 들었다.

이번 미션이 마지막인 만큼, 몰입과 나 스스로에 대한 성장에 좀 더 집중할 수 있는 시간이 되었으면 좋겠다 💪💪

profile
인생 망하기 전에 시작합니다

0개의 댓글