우테코 2주차 미션 숫자 야구 게임이 끝이 났다.

처음에 미션을 봤을 때는 생각보다 문제의 난이도가 쉬운 것 같았지만 패키지 구조, 메서드 분리, 네이밍 등을 신경쓰고 기능별로 커밋을 하면서 코드를 짜다보니 고민도 많이 하게 되고 문제를 어떻게 푸냐에 따라 스스로 난이도를 높여가면서 훈련하는 기분도 들었다.

 

규칙

숫자 야구 게임은 1 ~ 9 사이의 서로 다른 수로 이루어진 3자리 수를 맞추는 게임이다.

  1. 컴퓨터가 1 ~ 9 사이의 서로 다른 랜덤한 숫자 3자리를 생성한다.
  2. 플레이어는 1 ~ 9 사이의 서로 다른 숫자 3자리를 입력한다.
  3. 컴퓨터가 생성한 숫자와 플레이어의 숫자를 비교한다.
  4. 같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 낫싱이란 힌트를 얻는다.
  5. 힌트를 이용해서 컴퓨터의 숫자를 맞추면 승리한다.
    • 예) 상대방(컴퓨터)의 수가 425일 때
      • 123을 제시한 경우 : 1스트라이크
      • 456을 제시한 경우 : 1볼 1스트라이크
      • 789를 제시한 경우 : 낫싱

 

요구 사항

  • indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
  • 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.
  • JUnit 5와 AssertJ를 이용하여 본인이 정리한 기능 목록이 정상 동작함을 테스트 코드로 확인한다.
  • 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다.

 

라이브러리

camp.nextstep.edu.missionutils에서 제공하는 Randoms 및 Console API를 사용하여 구현해야 한다.

  • Random 값 추출은 pickNumberInRange()를 활용한다.
  • 사용자 입력값은 readLine()을 활용한다.

 

먼저 가장 큰 고민은 게임의 핵심으로 1~9 사이의 서로 다른 숫자 세자리에 대한 검증 처리였다. 어떻게 하면 깔끔하고 확실하게 예외 처리를 할 수 있을까 고민을 하다가 우테코를 시작하기전에 한번 봤었던 일급 컬렉션이 생각나서 다시 찾아보았다.

 

 

 

일급 컬렉션 (First Class Collection)의 소개와 써야할 이유

최근 클린코드 & TDD 강의의 리뷰어로 참가하면서 많은 분들이 공통적으로 어려워 하는 개념 한가지를 발견하게 되었습니다. 바로 일급 컬렉션인데요. 왜 객체지향적으로, 리팩토링하기 쉬운 코

jojoldu.tistory.com

 

일급 컬렉션은 컬렉션을 Wrapping 하면서, 그 외 다른 멤버 변수가 없는 상태를 말하는데 이에 대한 이점은 비즈니스에 종속적인 자료구조, Collection의 불변성, 상태와 행위를 한 곳에서 관리 등이 있다.

위와 같이 야구 게임의 숫자를 Wrapping하고 생성할때 검증을 거치면 이후 서비스 로직에서는 생성만 하면 된다. 그리고 테스트 코드를 통해 검증을 테스트할 수 있었다.

이렇게 게임 숫자를 객체로 보고 클래스를 만듦으로써 코드가 흝어지지 않고 한 곳에서 관리가 되면서 책임을 분리할 수 있게 되었다.

처음에 미션을 봤을 때는 생각보다 문제의 난이도가 쉬운 것 같았지만 패키지 구조, 메서드 분리, 네이밍 등을 신경쓰고 기능별로 커밋을 하면서 코드를 짜다보니 고민도 많이 하게 되고 리펙토링을 하다보면 스스로 난이도를 높여가면서 훈련하는 기분도 들었다.

 

 

위와 같이 야구 게임의 숫자를 Wrapping하고 생성할때 검증을 거치면 이후 서비스 로직에서는 생성만 하면 된다. 그리고 테스트 코드를 통해 검증을 테스트할 수 있었다.

 

 

이렇게 게임 숫자를 객체로 만듦으로써 코드가 흝어지지 않고 한 곳에서 관리가 되면서 책임을 분리할 수 있었다. 

 

게임에 대한 판정은 Umpire 클래스로 따로 분리했는데 가독성을 높이기 위해 고민을 많이 했었다. 자연스럽게 코드를 읽으면서 이해가 되도록 하다보니 playerPeek과 computerPeek이라는 변수를 선언했는데 gameCount 네이밍을 잘 했다면 변수 선언을 따로 안 해도 됐을거 같기도 하고.. 역시 어려운 것 같다.

 

 

게임 결과도 처음에는 리스트로 반환을 했지만 어떤 인덱스가 ball인지 스트라이크인지 헷갈릴 것 같아서 ball과 strike 정보를 담은 GameResult라는 클래스를 생성하였다. 이렇게 역할에 따라 클래스로 세분화를 해서 서비스 로직에서는 간단하게 흐름을 연결하는 식으로 작성을 했다.

 

 

이번 미션은 예외 처리와 테스트 코드에 대해서 아쉬움이 많이 남는데 코로나에 걸려서 몸 상태가 너무 안 좋았다. 4일 가량을 거의 누워 지내다가 30분 코딩하고 1시간 눕고를 반복해서 겨우 제출을 했는데 그래도 미리 좀 열심히 해놓았던게 정말 다행이라 생각했다. 3주차 미션이 시작하고 이틀이 지나서야 몸 상태가 돌아왔는데 지난 미션들의 공통 피드백과 이번 미션에 집중해야 될 부분을 한번 보면서 정리하고 3주차 미션은 열심히 해봐야겠다.

+ Recent posts