목차
기능 명세 작성하기
게임 시작
“숫자 야구 게임을 시작합니다.” 라는 문구를 출력한다.
1 부터 9 까지 서로 다른 3 개의 임의의 수를 선택한다.
•
Random 값 추출은 camp.nextstep.edu.missionutils.Randoms의 pickNumberInRange()를 활용한다.
숫자 입력
“숫자를 입력해주세요.” 라는 문구와 함께 3 자리의 서로 다른 숫자를 입력 받는다.
•
사용자가 입력하는 값은 camp.nextstep.edu.missionutils.Console의 readLine()을 활용한다.
입력값을 검증한다.
•
입력 값이 3 자리가 아니고, 숫자로만 이루어지지 않은 경우
•
입력 값에 중복되는 숫자가 있을 경우
•
입력 값에 0 이 포함된 경우
세 조건 중 하나라도 만족 시 IllegalArgumentException 을 발생 한다.
결과 출력
입력한 숫자와 컴퓨터가 선택한 숫자를 비교하여 결과를 출력한다.
•
스트라이크 : 같은 수, 같은 위치
•
볼 : 같은 수, 다른 위치
•
모든 숫자가 다를 경우 : 낫싱
•
게임 종료
◦
3 개의 숫자가 모두 같은 경우
◦
3 스트라이크
◦
“3 개의 숫자를 모두 맞히셨습니다! 게임 종료” 문구 출력
게임 재시작 / 종료 선택
“게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.” 문구 출력
사용자의 선택에 따라 게임 재시작 혹은 종료
•
1 입력시 : 게임 재시작
•
2 입력시 : 게임 종료
구현을 어떻게 하면 좋을까?
아직 객체지향적으로 코드를 짜는 것이 익숙치가 않다보니 지킬 수 있는 것부터 지켜봐야겠다는 생각을 했습니다. 그래서 유지보수와 확장을 쉽게 할 수 있도록 단일책임 원칙을 지켜서 기능 구현을 하기로 결심 했습니다!
단일책임 원칙
하나의 클래스는 하나의 역할을 가지도록 설계하자! (아래 내용은 구현 하면서 바뀔 수 있습니다.)
GenerateNumerList.java
•
입력받은 값과 컴퓨터의 값을 리스트로 만드는 역할
•
method
◦
generateInputNumberList()
◦
generateRandomNumberList()
PrintResult.java
•
결과를 만들고 출력하는 역할
•
method
◦
getResult()
◦
printResult()
ValidateInputNumber.java
•
사용자로부터 입력받은 숫자의 유효성을 검사하는 역할
•
method
◦
validateWithRegex()
◦
validateResult()
◦
validateCount()
◦
validateDuplicate()
Game.java
•
게임의 전체 흐름을 관장하는 역할
•
method
◦
gameStart()
◦
gameInProgress()
◦
gameEnd()
Application.java
초안 작성은 완료했지만…
초안 작성은 완료했지만 과연 이를 객체지향적으로 잘 짰는지 검증할 필요가 있었습니다. 그래서 객체지향 생활 체조에 대해 알아보았고, 적용할 수 있는 부분에 대해서 적용하였습니다. (관련 글은 아래 링크를 클릭해주세요.)
객체지향 생활 체조 원칙의 아래 두가지
•
모든 원시값과 문자열을 포장한다.
•
일급 컬렉션을 사용한다.
를 제외하고 아래 세가지를 지키도록 노력하였습니다.
•
한 메서드에 오직 한 단계의 들여쓰기만 한다.
•
else 예약어를 쓰지 않는다.
•
getter/setter/property 를 쓰지 않는다.
클래스 역할 분리
PrintResult.java 에 결과를 만들고 출력하는 두가지의 역할이 존재하여 이를 분리하였습니다. 처음에 막 만들다보니 두개를 하나의 역할로 봐도 무방 하겠다는 생각을 한 듯 합니다.
최소 접근 원칙과 캡슐화 적용
최소 접근 원칙
•
가능한 한 가장 제한적인 접근 제어자를 사용해라!
•
처음에는 private 으로 설정하고, 필요에 따라 접근 범위를 확장하는 것이 바람직합니다.
캡슐화
•
외부에서 객체의 내부 상태를 직접 수정하지 못하도록 하는 원칙입니다.
•
이를 위해 멤버 변수는 대부분 private 으로 선언하고, 필요한 경우 public 혹은 protected 메서드 를 통해 접근 및 수정을 허용합니다.
private final
왜 private final 을 쓰나요?
private final 을 사용하면 클래스의 외부에서는 해당 변수에 접근할 수 없고, 한 번 초기화 된 후에는 그 값이 변경되지 않습니다. 이러한 특징은 특히 객체 지향 프로그래밍에서 불변 객체(Immutable Object)를 생성할 때 유용합니다.
아맞다! 예외 메세지!
이제 해치웠나? 하는 순간 생각난 예외 메세지. 부랴부랴 작성해주었습니다.
회고
이렇게 1주차가 끝났네요. 많은 분들이 디스코드에서 자신의 경험과 공부 내용을 공유하는 모습이 정말 보기 좋았습니다. 저 또한 공유하고 싶은것들이 있었지만, 대부분이 이미 되어 있는 것들 이여서…
열정적인 모습들을 보며 자극을 많이 얻었고, 부족한 부분들을 돌아보며 다시한번 공부 계획을 다지고 위치를 파악해보는 시간을 가졌습니다.
앞으로 얼마나 더 어려운 문제들이 나올지… 걱정되지만 한편으로는 기대되네요 움핫핫
매 확신을 가지며 코스를 진행하고, 끝난 후에는 멋진 개발자가 되어 있도록 노력해야겠습니다!