사다리 타기 1단계 회고

후니팍·2023년 3월 11일
0
post-thumbnail

요구 사항 목록

  • 사다리 게임에 참여하는 사람에 이름을 최대5글자까지 부여할 수 있다. 사다리를 출력할 때 사람 이름도 같이 출력한다.
  • 사람 이름은 쉼표(,)를 기준으로 구분한다.
  • 사람 이름을 5자 기준으로 출력하기 때문에 사다리 폭도 넓어져야 한다.
  • 사다리 타기가 정상적으로 동작하려면 라인이 겹치지 않도록 해야 한다.
    • |-----|-----| 모양과 같이 가로 라인이 겹치는 경우 어느 방향으로 이동할지 결정할 수 없다.

고민 거리

예외 처리의 범위는 어디까지인가?

미션을 수행하다보면 사용자의 입력에 대한 에러 말고 동료 개발자가 저지를 수 있는 에러도 있다. 이번 미션에서는 가로 길이가 해당 사항이었다. 가로 길이를 사용자가 정하는 것이 아닌 사용자가 입력한 플레이어 수 - 1가로 길이가 되기 때문에 사용자로 인해 에러가 날 수는 없다. 하지만 다른 개발자가 실수로 가로 길이를 잘못 입력하여 사다리를 생성할 수도 있다. 이럴 때 에러가 발생하는데, 이에 대한 에러도 핸들링 해줘야 하는 지 고민이었다.

로직이 복잡해지면 복잡해질수록 개발자도 실수할 수 있다. 이럴 때 대비책이 필요하지 않을까?

나의 리뷰어는 위와 같이 말씀하셨다. 내 페어의 리뷰어는 반대로 개발자의 실수까지 예외 처리할 필요는 없을 것 같다고 말씀하셨다. 두 리뷰어의 말이 대립되는 것으로 보아 개인의 차이인 것 같다. 개발 시간이 충분히 주어지면 이런 에러까지 예외 처리하는 것이 좋을 것 같고 시간이 부족하다면 예외 처리하지 않아도 된다는 생각이 든다. 주어진 상황에 따라 우선순위를 두어 미션을 수행하면 될 것 같다.

DTO

domain에서 필요한 값을 view로 전달해야하는 상황에 dto를 사용하여 데이터를 전달하고 싶었다. 하지만 코치분들께서는 dto 사용을 지양하라고 말씀하셨다. 이해가 되지 않았다. dto를 사용하여 controller에서 domain의 필요한 정보만 뽑아내고 view로 전달해주면 그게 최선의 방법이라고 생각했었는데, 이 미션에는 dto를 사용할만한 사이즈가 아니라고 말씀하신다.

이에 리뷰어에게 질문을 했다. 리뷰어도 코치분들의 dto 사용을 지양하라는 말을 의아해하셨다. 음... 아마 코치분들께서는 조금 더 클래식한 관점에서 생각하게끔 유도한 것이 아닐까 생각이 든다.


구현 방법

크게 3가지 디렉터리로 패키지를 분리했다.

Player

자동차 경주와 플레이어를 입력하는 로직이 같아서 자동차 경주에서 거의 바뀐 것이 없다. Players라는 일급 컬렉션 안에 Player가 존재하고, Player는 필드로 PlayerName을 들고 있다.

사다리 타기에서는 Position이라는 플레이어의 위치를 저장하기 위한 객체를 만들었다. 사다리를 내려가면서 바뀌는 위치를 표현하기 위한 객체이다.

public class Player {

    private final PlayerName playerName;
    private final Position position;
    ...

    public void moveLeft() {
        position.moveLeft();
    }

    public void moveRight() {
        position.moveRight();
    }
    ...
}
public class Position {

    private int position;

    public Position(final int position) {
        this.position = position;
    }

    public void moveLeft() {
        position--;
    }

    public void moveRight() {
        position++;
    }

    public int getPosition() {
        return position;
    }
}

Ladder

사다리 객체이다.

가장 작은 단위는 Block이 담당한다. 사다리의 가로 한 칸 역할을 한다. 사다리의 칸이 비어있으면 Empty, 가로에 건널 수 있는 다리가 존재하면 Exist로 표현했다. 상태만을 가지기 때문에 enum으로 표현했다.

사다리 가로 한 줄을 담당하는 객체는 Line이다. Block 여러 개를 저장하고 있는 일급 컬렉션이다. 사다리를 생성하면서 여러 Block들을 넣어주었다. 이 때의 리스트의 길이는 플레이어 수 - 1 이다.

사다리 전체를 담당하는 객체는 Ladder이다. Line의 목록을 가지고 있는 일급 컬렉션이다.

Result

사다리를 다 내려왔을 때 결과를 담당하는 패키지이다. Players의 길이에 맞게 생성했고, Results라는 일급 컬렉션을 따로 만들어 Result를 관리했다. Result의 이름 검사와 get을 위한 메소드만 존재한다. 다른 패키지들과는 다르게 큰 역할은 없다.

피드백

사다리 생성 객체

처음에는 사다리 자체가 2차원 배열처럼 보이기 때문에 생성이 까다로울 것 같았다. 그래서 LadderMakerLineMaker라는 객체를 만들어 사다리의 생성을 담당하도록 했다. 오직 생성을 위한 객체이고 만들어둔 덕분에 LadderLine에서는 get을 위한 메소드 말고는 존재하지 않았다.

LadderLine의 역할은 get밖에 없다. 그저 저장용 객체가 아닐까? 하는 리뷰어께서 말씀하셨다. 맞는 말이었다. 하지만 지금 미션에서는 이를 위한 기능 말고 딱히 할 것이 없다고 생각했다. 내가 갈피를 잘 찾지 못하자 리뷰어께서 Maker와 사다리를 통합하는 것을 추천해주셨다. 사다리 생성을 위해 객체를 분리할 필요가 없었던 것이었다. 너무 과한 객체 분리였다. Maker에만 로직이 몰려있고 막상 진짜 게임을 위한 객체인 LadderLine은 아무런 역할을 하고 있지 않았다.
지난 생각을 버리고 Maker와 사다리를 통합하여 LadderLine에 생성을 위한 역할도 부여했다.

생성 객체는 생성자에서 사용하자

앞에서 말한 Maker를 통해 사다리를 생성할 때 나는 controller에서 생성했다. 책을 읽고 생성을 위한 객체는 생성할 객체의 생성자에서 생성하자는 교훈을 얻었다.


github


마무리

꼼꼼하지 못해 이런저런 지적을 많이 받았다. 부끄러워 차마 글로 남기지 못했다. 앞으로는 더 신중해지자...

profile
영차영차

1개의 댓글

comment-user-thumbnail
2023년 3월 11일

잘보고 감다!!!! 최고!!!!

답글 달기