26일 자정을 기점으로 우아한프리코스 첫 미션이 종료되었다.
비장한 각오로 시작한 만큼 이번 일주일은 하얗게 불태워졌다. 이렇게 오랜 기간 집중했던 게 얼마만인지.. 😅
물론 혼자가 아니었기에 가능했던 일들이었다. 우테코 커뮤니티가 있었기 때문이다. 유용한 정보를 함께 나누고, 서로의 관점을 나눠보는 환경이 든든하고 소중하게 다가왔다.
미션은 '얼마나 가독성이 좋아야하는가' 가 주된 포인트였다.
public class Score {
private final int strike;
private final int ball;
public Score() {
strike = 0;
ball = 0;
}
public Score(int strike, int ball) {
this.strike = strike;
this.ball = ball;
}
}
게임 점수를 관리하는 클래스이다. 이와 같이 모든 원시값을 클래스로 감쌌다. 각 클래스에 단일책임을 부여하였는지 여부가 한눈에 보였고, 빠뜨린 기능이 있는지 확인하는데도 유용했다.
public class Numbers {
private final List<Integer> numbers;
public Numbers(List<Integer> numbers) {
this.numbers = numbers;
}
//...//
}
해당 콜렉션에 불변을 보장하고 관련 로직이 한 곳에서 관리되니 유용했다.
public class Computer {
private static final int COMPUTER_NUMBERS_SIZE = 3;
private static final int RANDOM_NUMBER_MIN = 1;
private static final int RANDOM_NUMBER_MAX = 9;
private final Numbers numbers;
public Computer() {
this.numbers = new Numbers(createComputerNumbers());
}
private List<Integer> createComputerNumbers() {
List<Integer> computerNumbers = new ArrayList<>();
while (computerNumbers.size() < COMPUTER_NUMBERS_SIZE) {
addRandomNumber(computerNumbers);
}
return computerNumbers;
}
private void addRandomNumber(List<Integer> computerNumbers) {
int randomNumber = Randoms.pickNumberInRange(RANDOM_NUMBER_MIN, RANDOM_NUMBER_MAX);
if (!computerNumbers.contains(randomNumber)) {
computerNumbers.add(randomNumber);
}
}
//...//
}
의미있는 숫자를 상수로 관리하였다. 의미있는 상수명으로 코드 가독성이 훨씬 올라간게 보였다.
보통 오후 9시에 2차 작업을 시작하였다.
정신 차려보니 새벽 2시가 넘어가기 일쑤였다. 근데...
그 과정이 너무나도 재밌었다. 리팩토링을 통해 구색을 갖춰가는 나의 코드를 보니 재밌다 못해 가슴 설레기까지 했다. 밖에 나가있을 때면 집에 가는게 기다려졌고 얼른 자리에 앉아 코드를 치고 싶었다. 포비가 OT때 앞서 아침에 눈 뜨는게 기다려졌다는 말에 크게 공감했다.
private void validateInputDigit(String input) {
if (!input.matches(GAME_INPUT_RULE)) {
throw new IllegalArgumentException();
}
}
미션 중 입력값 중 숫자를 검증한 로직이다.
public class IllegalArgumentException extends RuntimeException {
//...//
}
public class RuntimeException extends Exception {
//...//
public RuntimeException() {
super();
}
public RuntimeException(String message) {
super(message);
}
//...//
}
public class IllegalArgumentException extends RuntimeException {
//...//
RuntimeException
을 상속받은 예외는 String
값으로 메시지를 파라미터로 전달받을 수 있었다. 각각의 검증에 대한 설명을 담지 못해 아쉬웠다.
public class Numbers {
private final List<Integer> numbers;
public Numbers(List<Integer> numbers) {
this.numbers = numbers;
}
public NumbersScoreDto calculateScore(Numbers other) {
int strike = 0;
int ball = 0;
for (int i = 0; i < numbers.size(); i++) {
int myNumber = this.numbers.get(i);
int otherNumber = other.numbers.get(i);
if (myNumber == otherNumber) {
strike++;
} else if (this.numbers.contains(otherNumber)) {
ball++;
}
}
return new NumbersScoreDto(strike, ball);
}
}
점수 계산 로직에서 들여쓰기 깊이를 줄이고 싶었으나 해결 못한 구간이었다...
Dto를 잘 활용했다면 극복가능하지 않았을까 생각한다.
indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법
함수(또는 메서드)를 분리하면 된다.
스펀지가 되어보자🧽