자동차 경주 게임 구현 - 비즈니스 로직과 UI의 분리

PPakSSam·2022년 1월 18일
0
post-thumbnail

순서

  1. 자동차 경주 게임 구현 - Code Convention
  2. 자동차 경주 게임 구현 - 객체를 객체스럽게 리팩토링 하자
  3. 자동차 경주 게임 구현 - 비즈니스 로직과 UI의 분리
  4. 자동차 경주 게임 구현 - 테스트 코드에서의 팁

이 포스트는 자바 플레이그라운드 with TDD, 클린코드를 들었다는 전제하에 쓴 글이며,
수업을 듣지 않았어도 전체 깃헙코드를 보고 어느정도 안다는 전제하에 쓴 글이다.


MVC패턴으로 구현을 하다보면 다음과 같은 실수를 많이 하게 된다.

public class Car {
    private int position;
    [...]

    private void print(int position) {
        StringBuilder sb = new StringBuilder();
        
        for(int i = 0; i < position; i++) {
            sb.append("-");
        }

       System.out.println(sb.toString());
    }
}

Car는 Model로서 비즈니스 로직을 담당하는 부분이지 View를 담당하는 부분이 아니다.
따라서 위의 print() 메소드 같은 출력을 담당하는 메소드는 Car 클래스에 있어서는 안된다.

그렇다면 어떻게 해야할까? 다음과 같이 코드를 작성해보자.

public class OutputView {
    public static final String GO_FORWARD_MARK = "-";
    
    public static void printCarStatus(List<Car> cars) {
        cars.forEach(car ->
            System.out.println(car.getCarName().getValue() + 
            " : " + renderingCurrentCarPosition(car)));
        System.out.println();
    }
    
    private static String renderingCurrentCarPosition(Car car) {
        StringBuilder currentPosition = new StringBuilder();
        for (int i = 0; i < car.getPosition(); i++) {
            currentPosition.append(GO_FORWARD_MARK);
        }

        return currentPosition.toString();
    }

비즈니스 로직을 담당하는 Model인 CarCars는 오직 데이터만 제공하고,
View 중 출력을 담당하는 OutputView에서 출력을 담당하게 했다.
이렇게 해야지 나중에 출력하는 부분이 바뀌었을 때 OutputView만 수정하고 Car와 Cars는 전혀 건들지 않아도 되게 되는 것이다.

넥스트 스텝에서는 이에 관한 내용을 다음과 같이 설명하고 있다.

  • 비즈니스 로직과 UI 로직을 한 클래스가 담당하지 않도록 한다.
  • 단일 책임의 원칙에도 위배된다.
  • 현재 객체의 상태를 보기 위한 로그 메세지 성격이 강하다면 toString()을 통해 구현한다.
  • View에서 사용할 데이터라면 getter 메소드를 통해 데이터를 전달한다.
profile
성장에 대한 경험을 공유하고픈 자발적 경험주의자

0개의 댓글