새로운 클래스에 대한 고민과 결정
Lv4에 들어서면서 자릿수에 대한 요구 사항이 있었다. 이에 따라 GameManager에서 필드로 digitSize를 가지고 있게 생각을 하였는데, 좀 더 객체 지향적으로 개선하기 위해 책임의 분리와 확장성을 고려하며 이에 따라 개선한 과정을 작성하려고 한다.
고민의 코드
public class GameManager {
private final BaseballGame baseballGame;
private final GameStats gameStats;
private final int digitSize;
public GameManager() {
this.gameStats = new GameStats();
this.baseballGame = new BaseballGame(new RandomNumberGenerator(), new Referee(), gameStats, digitSize);
}
public void run() {
Output.printInstructionsMessage();
boolean running = true;
while (running) {
final Screen command = repeat(this::inputCommand);
running = selectCommand(command);
}
}
private Screen inputCommand() {
Output.printLoadView();
final String command = Input.readSelectCommand();
return Screen.from(command);
}
private boolean selectCommand(final Screen command) {
if (command.equals(Screen.START)) {
baseballGame.start();
return true;
}
if (command.equals(Screen.RECORD)) {
Output.printGameStatus(gameStats.getAttemptsStore());
return true;
}
return !command.equals(Screen.EXIT);
}
}
현재 구조에서는 GameManager가 자릿수 설정, 게임의 흐름 제어, 그리고 게임 생성까지 모든 책임을 지고 있다.
개선 방향
- 자리수 설정 로직을 별도 객체로 분리:
- 자리수를 설정하는 책임을 GameManager가 가지는 대신, 별도의 설정 객체 (GameConfig)를 만들어 이곳에서 관리하려고 한다.
- 게임 생성과 관리를 별도 객체로 분리:
- GameManager는 게임의 흐름만 제어하고, 게임 생성이나 설정은 다른 객체가 관리하도록 했다.
- 유연한 확장을 고려:
- 자리수자릿수 설정이 향후 확장될 가능성이 있기 때문에, 자릿수 변경이나 설정 확장은 GameConfig 클래스에 위임하여 더 쉽게 관리할 수 있다.
개선 코드
package level4;
import static level4.util.Repeat.repeat;
import level4.domain.GameConfig;
import level4.domain.Screen;
import level4.view.Input;
import level4.view.Output;
public class GameManager {
private final GameConfig gameConfig;
private BaseballGame baseballGame;
public GameManager() {
this.gameConfig = new GameConfig();
this.baseballGame = gameConfig.createBaseballGame();
}
public void run() {
Output.printInstructionsMessage();
boolean running = true;
while (running) {
final Screen command = repeat(this::inputCommand);
running = selectCommand(command);
}
}
private Screen inputCommand() {
Output.printLoadView();
final String command = Input.readSelectCommand();
return Screen.from(command);
}
private boolean selectCommand(final Screen command) {
if (command.equals(Screen.SETTING)) {
Output.printRequestDigitSize();
gameConfig.configureDigitSize();
Output.printDifficulty(gameConfig.getDigitSize());
this.baseballGame = gameConfig.createBaseballGame();
baseballGame.start();
return true;
}
if (command.equals(Screen.START)) {
baseballGame.start();
return true;
}
if (command.equals(Screen.RECORD)) {
Output.printGameStatus(gameConfig.getGameStats().getAttemptsStore());
return true;
}
return !command.equals(Screen.EXIT);
}
}
package level4.domain;
import static level4.util.Repeat.repeat;
import level4.BaseballGame;
import level4.exception.input.InvalidDigitSizeException;
import level4.view.Input;
public class GameConfig {
private static final int DEFAULT_DIGIT_SIZE = 3;
private static final int MAX_DIGIT_SIZE = 5;
private static final int MIN_DIGIT_SIZE = 3;
private int digitSize;
private final GameStats gameStats;
public GameConfig() {
this.digitSize = DEFAULT_DIGIT_SIZE;
this.gameStats = new GameStats();
}
public void configureDigitSize() {
this.digitSize = repeat(this::getInputDigitSize);
}
private int getInputDigitSize() {
final int inputDigitSize = Integer.parseInt(Input.readDigitSize());
validateDigitSize(inputDigitSize);
return inputDigitSize;
}
public BaseballGame createBaseballGame() {
return new BaseballGame(new RandomNumberGenerator(digitSize), new Referee(), gameStats, digitSize);
}
public GameStats getGameStats() {
return gameStats;
}
private void validateDigitSize(final int digitSize) {
if (digitSize < MIN_DIGIT_SIZE || digitSize > MAX_DIGIT_SIZE) {
throw new InvalidDigitSizeException("자리수는 3, 4, 5 중 하나여야 합니다! 다시 입력해 주세요.");
}
}
public int getDigitSize() {
return digitSize;
}
}
결과
- 책임 분리: 자리수 설정은 GameConfig, 게임 제어는 GameManager 가 담당하게 되어 책임이 명확히 분리된다.
- 유연성: 자리수 설정이 게임 생성에 영향을 미치지만, GameConfig에서 이 역할을 담당하므로 확장하기 쉬워졌다.
- 확장성: 자리수 설정 로직이나 다른 설정을 추가할 때 GameConfig만 수정하면 되고, 게임 로직에는 영향이 덜 가므로 유지보수가 용이해졌다.
'회고' 카테고리의 다른 글
일정 관리 서비스 회고 및 리팩토링 (0) | 2024.10.07 |
---|---|
일정 관리 과제 회고 (1) | 2024.10.03 |
숫자 야구 게임 전체 회고 (2) | 2024.09.24 |
숫자 야구 게임 Lv2 Lv3 회고 (0) | 2024.09.18 |
계산기 도전 과제 회고 (0) | 2024.09.07 |