✅ a ~ b
사이의 서로 값이 다른 n자리
의 정수를 랜덤으로 생성한다.
▪️ Default Setting : `1 ~ 9`사이의 서로 값이 다른 `3자리`의 정수
✅ 게임 시작 문구 출력
✅ 사용자에게 a ~ b 사이의 서로 값이 다른 n자리의 정수
를 입력 받는다.
▪️ 입력받은 input이 비어있을 경우 예외처리<br/>
▪️ 입력받은 input이 숫자가 아닌 문자가 포함될 경우 예외처리
▪️ 입력받은 input에 중복된 숫자가 있을 경우 예외처리
✅ 사용자 input 숫자와 랜덤 생성 정수의 자리수를 비교해 출력할 힌트를 계산한다.
▪️ 숫자의 값은 같지만 자리수가 다른 경우의 수 n개 : `n볼`
▪️ 숫자의 값과 자리수가 모두 같은 경우의 수 m개 : `n스트라이크`
✅ 계산된 힌트를 아래 양식으로 출력한다
▪️ 볼 n개, 스트라이크 0개가 존재할 때 : `n볼`
▪️ 볼 0개, 스트라이크 n개가 존재할 때 : `n스트라이크`
▪️ 볼 n개, 스트라이크 m개가 존재할 때 : `n볼 m스트라이크`
▪️ 볼 0개, 스트라이크 0개가 존재할 때 : `낫싱`
✅ 게임 클리어 여부 판단
▪️ n스트라이크가 아니라면`, 다시 사용자에게 입력을 숫자를 받고, 힌트를 출력한다.
▪️ n스트라이크를 맞추었다면`, 아래 메세지를 출력하고 사용자에게 플래그를 입력받는다.
▪️ n개의 숫자를 모두 맞히셨습니다! 게임 종료`
▪️ 게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.`
▪️ 입력받은 input이 1과 2가 아닌 숫자일 경우 예외처리
▪️ 입력값에 따라 게임을 재시작하거나 종료한다.
-
input 숫자의 범위가 변하더라도(1~9), 자리수가 변하더라도 대응이 손쉽게 가능해야 한다.
GameConfig
파일에서NUMBER_LENGTH
변수의 value를 변경해 손쉽게 변경이 가능하다.
개발 요구사항에서 자릿수 요청까지 처리하는 문제였다면, 더욱 OCP를 준수하는 코드 작성이 가능했을 것 같다.
숫자 3자리 | 숫자 4자리 | 숫자 5자리 |
---|---|---|
-
영감을 얻게 해줬던 한 마디
객체는 '자율적인 존재'라는 점을 명심하라. < 중략 > 객체는 스스로의 행동에 의해서만 상태가 변경되는 것을 보장함으로써 객체의 자율성을 보장한다. - 객체지향의 사실과 오해 中
-
First-class collection + Static Factory Method 활용
public class Number { private final List<Integer> numbers; // Player Input Number Constructor private Number(String input) { validateEmpty(input); validateNumberLength(input); validateContainOnlyNumber(input); validateContainDuplicatedNumber(input); this.numbers = convertInputNumber(input); } // Computer Generated Number Constructor private Number(List<Integer> computerNumber) { this.numbers = computerNumber; } }
-
일급 컬렉션과 생성자 검증을 사용해
numbers
에 유효하게 검증이 끝난 숫자만 들어오도록 설계 -
playerNumber와, computerNumber의 생성자는 서로 다른 파라미터를 지니기 때문에, 개발자가 사용 간 혼동 가능
해당 문제를 해결하기 위해, 생성자를private
으로 제한하고, 의미있는 메소드로만 생성자를 호출하도록 설계// Computer Generated Number Constructor public static Number generateRandomNumbers() { List<Integer> randomNumbers = new ArrayList<>(); while (randomNumbers.size() < NUMBER_LENGTH.getValue()) { int number = pickNumberInRange(RANDOM_NUMBER_MINIMUM.getValue(), RANDOM_NUMBER_MAXIMUM.getValue()); if (!hasDuplicatedNumber(randomNumbers, number)) { randomNumbers.add(number); } } return new Number(randomNumbers); } // Player Number Static Factory Method public static Number inputPlayerNumbers() { String playerNumbers = InputView.askPlayerNumbers(); return new Number(playerNumbers); }
-
정적 팩토리 메소드 명에 의미를 부여하고, 개발자가 직관적으로 해석할 수 있도록 했고,
일급 컬렉션을 활용해 검증이 끝난 유효한 값만 리스트에 담을 수 있게 되었다!