[우아한 테크코스-프리코스 1주차] 숫자야구게임 설계

우아한 테크코스 1주차 미션 숫자 야구 게임 GitHub Link

설계? 구현?


우아한 프리코스에서의 과제 진행 요구 사항은 “기능을 구현하기 전 docs/README.md에 구현할 기능 목록을 정리해 추가” 하는 것이였다. 구현하기 전에 정리해서 기능 구현 설계하는 것이 익숙치가 않아서 먼저 요구 사항부터 정리를 해보았다. 이 전에 작은 프로젝트를 진행했을 때에는 무턱대고 구현부터 시작해서 수정하는 것에 가장 큰 시간을 소모했던 나의 과거가 생각나며 굉장히 비효율적이였구나 생각이 들었다.

기능 요구 사항


## 상대방 컴퓨터
- 3 자리 숫자 문자열을 가짐
- 1 ~ 9까지 서로 다른 임의의 수 3 개 선택 
  - camp.nextstep.edu.missionutils.Randoms - `pickNumberInRange()`
- 플레이어 - 컴퓨터 개수 계산
  - 스트라이크
    - 3스트라이크: 게임 재시작/종료 구분
  - 볼
  - 낫싱

## 입력
- 플레이어가 추측하는 컴퓨터의 서로 다른 3 개의 숫자
    - camp.nextstep.edu.missionutils.Console - `readLine()`
- 게임 재시작/종료를 구분하는 1과 2 중 하나의 수
**잘못된 값 입력 시 `IllegalArgumentException` 발생 후 종료**

## 출력
- 플레이어 - 컴퓨터 개수 계산 출력
- 하나도 없는 경우(낫싱) 경우 출력
- 3개의 숫자를 모두 맞힐 경우(3스트라이크) 경우 출력
- 게임 시작 문구 출력
- 게임 재시작/종료 문구

.
.
.

처음으로 정리해본 요구사항은 다음과 같았다. 먼저, 기능 요구 사항, 프로그래밍 요구 사항, 과제 진행 요구 사항을 보고 정리했다. 다음으로 요구사항을 토대로 구체화해서 어떻게 구현할 것인지 “구현 기능 목록”을 설계해서 목록을 정리해보았다.

구현 기능 목록



# 구현 기능 목록
## Model
- ComputerModel
  - Field 
    - [x] 중복되지 않은 임의의 숫자 3 개
  - Method
    - [x] 플레이어 - 컴퓨터 점수 계산
      - 숫자 포함 O, 자리 x -> 볼
      - 숫자 포함 O, 자리 O -> 스트라이크

## View
- InputView
  - Method
    - [x] 플레이어 수 입력 
    - [x] 게임 재시작/종료 1과 2중 하나의 수 입력 
    - camp.nextstep.edu.missionutils.Console - `readLine()` 사용
- OutputView
  - Method
    - [x] 플레이어 - 컴퓨터 볼 점수 출력
    - [x] 플레이어 - 컴퓨터 스트라이크 점수 출력
    - [x] 하나도 없는 경우(낫싱) 경우 출력
    - [x] 3개의 숫자를 모두 맞힐 경우(3스트라이크) 경우 출력
    - [x] 게임 시작 문구 출력
    - [x] 게임 재시작/종료 문구 출력 

## Controller
- StateController
  - Method
    - [x] 게임 시작 시 새로운 computerModel 객체 반환
    - [x] 게임 재시작/종료 조정
    - [x] player가 3 strike에 성공했는 지 체크하는 함수 생성
    - [x] 점수에 따라 score 출력하는 함수 생성

## RandomNumber
  - Method
    - [x] 중복되지 않은 임의의 숫자값 3 개 반환
      **camp.nextstep.edu.missionutils.Randoms - `pickNumberInRange()`**
## Exception
  - Method
    - [x] 재시작/종료 입력값이 1 혹은 2가 아닐 경우 exception 발생
    - [x] 사용자가 입력한 숫자가 세 자리가 아닐 경우 exception 발생
      **사용자가 잘못된 값을 입력한 경우 `IllegalArgumentException` 발생**

.
.
.

구현하기 전에 설계를 먼저 함으로서 무작정 구현부터 시작하는 것보다 목록을 통해 다음으로 구현해야 할 부분, 지금까지 구현한 부분과 앞으로 남은 부분들에 대한 순서를 고려함으로서 효율적인 프로그래밍을 하기 위함이라고 생각했다. 처음에 설계를 먼저 하는 것이 익숙하지는 않아서 맨 처음 commit한 구현 기능 목록에서 함수 정의 위치나, 기능들을 조금씩 수정하는 일이 생겼지만 이렇게 불가피한 수정과정이 무작정 구현부터 하는 것보다 훨씬 효율적이라는 것을 몸소 체감했다.
또한, 이런 목록을 기반으로 하나의 기능을 구현할 때마다 commit 을 남겨놓으니 나중에 확인하기에도 훨씬 깔끔한 것을 알 수 있었다. 이전에는 이것저것 수정하고 구현하는 과정을 하고 한 번에 commit을 진행했었는데, 이런 목록을 기반으로 commit 메세지에 간단하게 요약할 수 있어서 구현 진행 단계를 commit 목록만 확인해도 보였다.

나의 첫 번째 설계


우아한 프리코스를 통해 처음으로 설계 목록 문서를 작성해보았다. 프로그램 설계를 해본 적이 없던 나는, 무작정 수정해가면서 구현하는 방식으로 해왔었는데, 왜 먼저 설계를 한다는 생각을 떠올리지 못했을까? 싶었다. 처음에는 기능 구현 목록을 조금 포괄적으로 적은 감이 있었어서, 구현하는 과정에서 미리 생각하지 못한 부분을 마주하는 바람에 중간에 로직을 수정하는 과정을 겪었다. 이를 통해 구현 목록만 보아도 구현을 할 수 있도록 디테일하게 설계하는 것이 수정하는 것에 시간을 요소하는 것을 줄일 수 있음을 깨달았다. 규모가 큰 프로젝트일 수록 구현하기에 앞서 설계가 탄탄해야 중간에 수정하는 과정에서 시간 낭비를 하지 않겠구나..



앞으로의 설계는?


  1. 요구사항 정리
  2. 1.을 기반으로 구현해야할 기능 목록 정리
  3. 비즈니스 로직 구체화, 기능 목록 보완
  4. 구현
  5. 기능 목록 체크