체스 미션을 진행하면서 커맨드 패턴에 대해 듣게 되었다.

디자인 패턴을 사용하는데만 집중하는 것은 좋지 않다는 말이 있지만,

분기문에 대한 불편함, 찝찝함을 해소하고 싶었다.

알면서 안쓰는 것과 모르면서 안쓰는 것과는 큰 차이이기 때문에 일단 적용해 보고자 했다.

어떻게 쓰는 것인진 모르겠으나, 커맨드에 따라 책임을 분리한다는 생각만 가지고 내 나름대로 구현을 해 보았다.

커맨드 패턴과 상태 패턴의 결합

Command 인터페이스에서 커맨드를 실행하는 execute()를 가지고 있다.

public interface Command {

    State execute(Optional<ChessGame> chessGame, List<String> input);

    String getCommand();
}

사용할 커맨드들을 객체로 만들어서 Command를 구현하도록 한다. 내가 사용한 커맨드는 Start, Move, Status, End 이다.

커맨드를 관리하는 Commands를 만들어줘서 사용 가능한 커맨드를 관리한다.

public class Commands {

    private final Map<String, Command> commands;

    public Commands(List<Command> commands) {
        this.commands = commands.stream()
                .collect(Collectors.toMap(Command::getCommand, Function.identity()));
    }

    public Command findCommand(String input) {
        return commands.getOrDefault(input, new IllegalCommand());
    }
}

다음과 같이 커맨드를 사용하는 곳에서 어떤 커맨드를 사용할 수 있는지 정해줄 수 있다.

Commands commands = new Commands(List.of(new MoveCommand(), new EndCommand(), new StatusCommand()));

사용하지 않는 커맨드라면 IllegalCommand를 exceute하게 되고, 여기에는 UnsupportedException을 발생시키도록 만들었다.

다음은 이를 구현하는 MoveCommand 클래스이다. 커맨드를 실행하면 Move 객체를 생성한다.

    @Override
    public State execute(Optional<ChessGame> chessGame, List<String> input) {
        return new Move(chessGame.orElseThrow(IllegalArgumentException::new),
                input.get(1), input.get(2));
    }

커맨드에 따라서 상태에 맞는 객체를 생성하도록 했다.

느낀점

사실 상태를 체스 게임에 적용하는 것이 보통인데, 나는 만들다 보니 컨트롤러를 상태로 제어하게 되었다.

컨트롤러를 상태로 제어하기 때문에 파라미터로 InputViewOutputView를 넣어주는 것이 조금 부자연스러운 느낌이 있다.

또한, Ready 상태에서는 ChessGame를 초기화 하지 않은 상태이기 때문에 Optional<ChessGame> 으로 래핑해주었다.

파라미터에 Optional을 사용하는 것이 안좋아 보이지만 당장은 어쩔 수 없이 사용하고 나중에 리팩토링 해야겠다.

분기문이 확연하게 줄어든 것을 느낄 수 있었다.

Status는 나중에 추가된 상태인데, 코드의 확장성이 나아진 것을 바로 느낄 수 있었다.

특히, 상태에 따라서 사용 가능한 커맨드를 제어해주는 것이 괜찮다고 생각했다.

'회고 > 우아한테크코스' 카테고리의 다른 글

[레벨 1] 레벨 로그  (0) 2023.03.28
2023.03.27 일일 회고  (0) 2023.03.28
2023.03.21 일일 회고  (0) 2023.03.22
2023.03.20 일일 회고  (0) 2023.03.21
[레벨 1] 사다리 미션 회고  (0) 2023.03.20

+ Recent posts