[우아한테크코스] 프리코스 3주차 회고

이호석·2022년 11월 16일
2
post-thumbnail

🚀 로또

3주차에 주어진 미션은 숫자 야구 미션입니다.
미션에 대한 규칙 및 구현 코드는 다음 저장소에 정리되어 있습니다.
https://github.com/HiiWee/java-lotto

🔒 제약 사항

  • 미션은 기능 요구 사항, 프로그래밍 요구 사항, 과제 진행 요구 사항 세 가지로 구성되어 있다.
  • 세 개의 요구 사항을 만족하기 위해 노력한다. 특히 기능을 구현하기 전에 기능 목록을 만들고, 기능 단위로 커밋 하는 방식으로 진행한다.
  • 기능 요구 사항에 기재되지 않은 내용은 스스로 판단하여 구현한다.

📌 기존 요구 사항

📌 추가된 요구 사항

  • 함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다.
    • 함수(또는 메서드)가 한 가지 일만 잘하도록 구현한다.
  • else 예약어를 쓰지 않는다.
    • 힌트: if 조건절에서 값을 return 하는 방식으로 구현하면 else를 사용하지 않아도 된다.
    • else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데
      switch/case도 허용하지 않는다.
  • Java Enum을 적용한다.
  • 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다.
    • 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다.
    • 단위 테스트 작성이 익숙하지 않다면 test/java/lotto/LottoTest를 참고하여 학습한 후 테스트를 구현한다.

📌 라이브러리

  • camp.nextstep.edu.missionutils에서 제공하는 Randoms 및 Console API를 사용하여 구현해야 한다.
    • Random 값 추출은 camp.nextstep.edu.missionutils.Randoms의 pickUniqueNumbersInRange()를 활용한다.
    • 사용자가 입력하는 값은 camp.nextstep.edu.missionutils.Console의 readLine()을 활용한다.

🚀 미션을 시작하면서

❗️ 새로운 목표

1. 클래스(객체)를 분리하는 연습
2. 도메인 로직에 대한 단위 테스트를 작성하는 연습

미션 메일과 함께 새로운 2가지의 목표를 같이 전달받았다.
메소드 분리를 넘어 비슷한 것들끼리의 객체를 분리하고, 도메인 로직에 대한 단위 테스트를 작성해야 한다!

위의 목표에서 도메인 로직이라는 단어는 확 와닿지 않았던 것 같아 도메인에 대해 많은 자료를 찾아봤던 것 같다.

여러 자료를 찾아보고 공부한 결과 도메인은 도메인 로직은 '현실 세상의 문제'를 해결하는 코드를 의미했습니다. 즉, 비즈니스에 대한 의사결정을 하고 있는지에 따라 도메인 로직이 결정되고, 나머지 코드들은 그 결정을 하기 위한 입력값을 만들거나 과정에서 나온 결과물을 보여주는 역할들이 대부분이었습니다.

지난 미션인 숫자 야구를 다시 살펴보며 실질적으로 숫자 야구에서의 문제를 해결하는 코드들과 입력값을 만들거나 결과물을 보여주는 코드를 구분할 수 있었고, 이를 통해 3주차 미션에 대한 인사이트를 조금 얻을 수 있었습니다.

살아있는 기능목록

처음부터 완벽한 기능목록을 만들기보단, 중간중간 추가되는 기능목록이 있다면 추가해도 된다. 살아있는 문서를 만들자!

2주차의 피드백이었습니다. 천 명이 넘는 사람들에 대한 공통 피드백인데 어째서 항상 정곡을 찔리는 느낌인지 신기했습니다.

미션을 시작할 때 항상 완벽한 기능목록을 만들고 구현단계로 넘어가려 했고, 내가 만족할 만한 기능 목록이 작성되지 않으면 불안하고, 걱정이 많았었는데 위의 피드백을 듣고 조금은 편안한 마음으로 기능 목록을 작성할 수 있었습니다.

특히 눈에 확연히 보이는 로직 적인 부분이 아닌 예외 처리에 관한 내용들은 초반에 목록들을 정리하기 힘들고, 구현 과정 중에 파악되는 경우가 있으므로 매 순간에 유연하게 대처할 수 있다는 점이 가장 좋았습니다!

도메인 로직에 대한 생각

도메인 로직에 대한 이해는 어느 정도 되었지만, 현재 미션에서 어떤 방식으로 구성해야 할지 고민이 되었습니다.
로또 프로그램이므로 당연히 로또라는 도메인은 생각되었지만, 그 외의 것들이 문제였습니다.

어디서 어떻게 판단해야 할까?
일단 실생활에서 어떤 방식으로 로또라는 프로그램이 동작하는지 생각해봤습니다.
1. 사용자가 로또를 구매함
2. 토요일이 되면 사용자는 로또를 본인이 당첨 번호와 비교하여 결과를 알게 됨
3. 당첨됐다면 금액을 교환함

여기서 로또, 당첨 번호, 금액이라는 도메인을 찾을 수 있었습니다.

미션 중에서는 금액이라는 도메인은 굳이 하지 않아도 되겠다라는 생각으로 이를 서비스 로직에서 구현했지만, 지금 생각해보니 도메인으로 넣는 편이 좋을 것 같다는 생각이 드네요

다음으로 추출한 도메인을 바탕으로 기본 로직들의 위치를 생각했습니다.

  1. 생성된 로또를 검증 -> Lotto 도메인(생성은 바깥에서 했지만, 조금 아쉬운 선택이라 생각됩니다.)
  2. 당첨 번호를 생성 -> WinningNumber 도메인
  3. 당첨된 결과 메시지를 생성 -> Lotto 도메인(결과 저장용 도메인으로 나눴다면 조금 더 좋았을 것이라 판단됩니다.)

위와 같이 로직들을 정의하고 실제 구현을 하게 되니, 객체에 메시지를 보내라는 말의 의미가 조금은 다가오지 않았나 생각이 들었습니다 ㅎㅎ

미션이 종료되고 코드 리뷰를 하면서 정말 많은 도메인을 세분화한 경우도 있었고, 큰 덩어리 도메인 위주로 작성하신 분들도 있었습니다.

개인적으로 도메인을 많이 세분화 하는 것과 그렇지 않은 경우는 trade-off의 관계가 아닐까 하는 생각이 듭니다.

전자의 경우 일단 기능 자체가 세분되어있으므로 하나의 메소드가 한 가지의 기능만을 하고 있었고, 코드 길이가 적어 가독성이 좋았습니다. 하지만, 하나의 메소드를 파고들면 깊이가 깊어지므로 오히려 가독성이 안 좋다고 생각이 들기도 했습니다.

후자의 경우 큰 덩어리 위주라 각 기능들의 깊이감은 낮았지만, 이해하기 쉬웠습니다. 하지만, 도메인 로직에 있어도 좋을법한 로직들이 서비스 로직에 존재하는 경우도 있었고, 한 메소드가 여러 기능을 하는 경우도 존재했습니다.

4주차 미션에서는 나만의 도메인을 나누는 기준을 익히고 배우는 것을 목표로 삼으면 좋겠다는 생각입니다!

테스트 코드는 피드백 왕

온보딩을 제외한 모든 미션에서 테스트 코드의 언급은 항상 꾸준하게 있었습니다.
이번 미션에선 도메인 로직에 대한 단위 테스트가 핵심 키워드였습니다. 2주 차 때는 나름으로 열심히 작성한 테스트 코드에서 발견하지 못하는 몇 개의 오류들을 보고, 더욱 치밀하게 작성해야겠다는 생각이 있었습니다.

따라서 하나의 기능이 구현되면 반드시 테스트 코드를 작성하려 노력했습니다.
다만, 왜 하필 도메인 로직에 대한 단위 테스트만을 이번 미션에서 강조했느냐는 의문이 들었습니다.

미션을 진행하며 도메인 로직이 테스트 코드의 거의 전부라는 사실을 금방 깨달을 수 있었는데
비즈니스적인 의사결정을 하는 도메인 로직이 정상적으로 동작하는 것이 보장된다면, 나머지 input 값과 도메인 로직으로부터 발생한 output의 값들은 정상적인 것이 보장되기 때문입니다.

결국 핵심 도메인 로직의 동작 여부가 제일 중요한 포인트였습니다.

로또 미션은 2주차 숫자 야구 미션보다 많은 요구사항을 던지고 있었고, 그에 따른 코드들의 양도 많아졌습니다. 미션을 진행하며 단위테스트를 꾸준하게 진행한 점은 이런 부분에서 큰 도움을 주고 있었습니다.

새로운 기능이 추가되면 지금까지 작성한 기능들이 정상적으로 동작해야 새로운 기능들도 정상 동작함을 판단할 수 있습니다. 테스트 코드는 지금까지 작성한 로직들이 검증된 로직임을 보장해주는 역할을 해주므로 새로운 기능을 걱정 없이 개발할 수 있었습니다. 더불어 기존의 코드들이 리팩토링 되는 경우에도 테스트 코드를 통해 정상적으로 변경됐는지 판단할 수 있었습니다.

3주차 미션에서 테스트 코드가 주는 도움은 너무나도 컸습니다. 과거에는 테스트 코드가 단순히 보조적인 도구 아닌가란 생각이었지만, 이번 미션을 통해 오히려 메인 로직보다 중요할 수도 있겠다는 생각이 듭니다. 그래서 TDD라는 개발 방법론이 생기고, 많은 사람이 그것에 대해 입을 모아 칭찬하는 거였구나 공감이 되었던 미션이었습니다.

4주차의 개인 목표

나름 도메인을 나누려고 노력했지만, 다른 사람들의 코드를 보면서 내 코드는 도메인 로직이 서비스 로직에 많이 포함된 것 같다는 느낌이 들었습니다.

  • 4주차는 도메인을 조금 더 치밀하게 구성하고, 객체 간의 메시지 전달을 통해 객체를 객체답게 사용해보도록 노력하려 합니다.

  • 더불어서 테스트 코드를 단순히 도구가 아닌, 리팩토링 해야 하는 메인 로직처럼 조금 더 치밀하게 작성하려 합니다

  • MVC에 대해 조금 더 공부하고, 조금 더 확실하게 역할을 나누고 기능을 작성하려 합니다!

4주차 미션은 더욱더 빡빡해진 요구사항이 추가되었기에 공통 피드백과 개인적인 목표를 잘 지켜야 할 것 같다는 생각입니다!

profile
꾸준함이 주는 변화를 믿습니다.

1개의 댓글

comment-user-thumbnail
2022년 11월 20일

잘보고갑니다!

답글 달기