본문 바로가기
우테코 프리코스 7기

11, 12일차 - 기능 구현 해보기

by 청원뿔세포 2024. 11. 1.

1. 핵심 객체

저번 1주차 과제에서는 절차지향적으로 설계하였다. 하지만 2주차부터는 유지보수가 좋은 객체지향적으로 설계해보기 위해 이번 과제에서 핵심적인 객체에 대해 고민해보았다.

  • 자동차
    • 이름과 전진 횟수
    • 전진하기 기능
      • 전진 횟수 +1
      • 언제 전진하는가?

자동차 여러대가 주어지지만 자동차 객체를 만들고 그 자동차 객체를 리스트나 배열 형태로 만들어 놓으면 좋겠다고 생각했다.

Car

  • String name
  • int winStack
  • car(string name) 생성자
    • this.name = name
    • this.winStack = 0
  • getter
    • name
    • winStack
  • plusWinstack
    • this.winStack++
  • goRound
    • 0~9 랜덤으로 뽑아 4이상 나오면 plusWinstack 호출
  • CarNameEmptyValidator
    • 자동차 이름이 입력되지 않은 경우 검증
  • CarNameLengthLimitValidator
    • 자동차 이름이 5자보다 큰 경우 검증

2.Dto에 대해 고민

1주차 과제에는 Dto에게 너무 많은 역할을 줬었던 잘못을 했었다. 그래서 이번에는 데이터의 형태와 getter만 넣어줬다.

public class CarsDto {
    private List<Car> cars;

    public CarsDto(List<Car> cars) {
        this.cars = cars;
    }

    public List<Car> getCars() {
        return cars;
    }
}

자동차 객체를 여러개 갖고있는 리스트가 필요했고, 이 리스트를 가지고 비즈니스 로직이 동작하기 때문에 이 Dto를 만들게 되었다. 하지만 Dto로 만들지 말고 그냥 domain에 클래스로 선언해도 됬을 것 같다는 생각이 들었지만 큰 기능이 없다고 생각하여 Dto로 결정하였다.

3. 입출력

입력

입력을 2번 받아야 하지만 각 입력마다 안내문구가 달랐다. 그래서 결국 입력을 2개로 만들기로 하였다.

입력을 Console.readline() 으로 받는다. 1주차에 다른사람들 코드를 보면서 입력이 끝나면 메모리 낭비를 막기 위해 Console.close() 로 닫아야 한다는 것을 알았다.

2개의 입력을 만들어 각각 Console.close() 를 달아주니 2번째 입력에서 콘솔창이 닫쳐버려 입력을 받을 수 없는 상황이 되었다. 그래서 2번째 입력에만 Console.close() 를 달아두었다.

출력

시도 횟수마다 결과를 계속 출력해줘야하는 출력 조건이 있었다. 이런 반복되는 부분을 controller 에서 루프문을 만들고 그 안에서 출력 메서드를 호출해서 해결하기로 했다.

4. 서비스

본격적인 비즈니스 로직이 작성되는 계층이였다.

  • raceSetting
    • 자동차 이름들을 입력받아 자동차 계층으로 파싱해준다.
  • playOneRound
    • 각 시도 횟수마다 자동차 객체는 전진을 시도한다.
  • roundService
    • 시도할 횟수를 숫자로 바꿔준다.
  • raceResult
    • 경주가 끝난 자동차들 중에서 우승자를 뽑는다.

시도할 횟수를 round로 정의하고 모델로 객체화 시켜야 했었나 고민을 했었지만 서비스에서 간단하게 처리할 수 있다고 생각하여 서비스에 두었다.

5. 컨트롤러

컨트롤러는 입력을 받아 출력을 해주는 절차지향형으로 구현하였다.

자동차들을 입력 받고 raceSetting 서비스에 자동차들을 넣어준다. 결과물로 carsDto 를 만들어낸다.

시도할 횟수를 입력받고 roundService로 숫자로 바꾸어 준다.

시도할 횟수만큼 루프를 돈다. carsDto 를 playOneRound 서비스에게 주어 한 라운드를 경주하고 그 결과를 carsDto 에 다시 저장한다. 그리고 그 결과를 outputEachRound로 출력해준다.

루프 종료 후 raceResult가 carsDto 를 가지고 결과를 산출한다. 결과를 가지고 최종 우승자를 출력한다.

    public void run() {
        String inputCars = InputView.inputCars();
        String roundCount = InputView.inputRounds();

        RaceService raceService = new RaceService();
        CarsDto carsDto = raceService.raceSetting(inputCars);

        int round = raceService.roundService(roundCount);
        OutputView.outputBeforeRound();
        for (int i = 0; i < round; i++) {
            carsDto = raceService.playOneRound(carsDto);
            OutputView.outputEachRound(carsDto);
        }
        List<String> result =  raceService.raceResult(carsDto);
        OutputView.outputRaceResult(result);
    }

 

코드의 계층 구조는 다음과 같다.

 

댓글