강신규

[우테코 프리코스/7기] 프리코스 2주 차 회고 본문

우아한테크코스

[우테코 프리코스/7기] 프리코스 2주 차 회고

kangnew 2024. 11. 12. 11:23

 

최종코드 :

https://github.com/singyuKang/javascript-racingcar-7/tree/singyuKang

 

GitHub - singyuKang/javascript-racingcar-7

Contribute to singyuKang/javascript-racingcar-7 development by creating an account on GitHub.

github.com

 

 

1. 기능 구현 사항 정리

1주차에서 느꼈던 기능 단위 코드를 분리를 통해 README를 작성하였습니다.

 

# javascript-racingcar-precourse

## ✏️ 과제 진행 요구 사항 - 구현할 기능 목록

## 입력 함수 구현

- [x] 사용자의 입력을 받는 함수 구현 '경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분).'를 출력하고 자동차 이름을 쉼표 기준으로 나누어 출력받습니다.

## 입력 값 처리

- [x] 이름을 쉼표 기준으로 나누어 배열형태로 저장합니다.
- [x] 각 이름의 길이가 5자 이하인 경우만 가능하도록 합니다.

## 무작위 함수 구현

- [x] 0~9 사이의 무작위 숫자를 반환하는 함수 구현

## 시도할 획수 입력 구현

- [x] '시도할 횟수는 몇 회인가요?' 를 출력하고 시도할 횟수를 입력받는다.
- [x] 입력값이 숫자 , 양수 인지 확인합니다.
- [x] 입력값이 이상할 경우 에러 처리

## 각 차량 무작위 숫자 처리

- [x] 차량별로 0~9 사이의 무작쉬 정수 값을 받습니다.

## 각 차량의 무작위 값이 4 이상인 경우에 전진

- [x] 무작위 정수 값이 4이상인 경우 자동차를 1회 전진합니다.

## 실행 결과 출력

- [x] 각 처량 상태 출력해줍니다.
- [x] 최종 우승자를 출력해줍니다.

 


2. domain Class 정의

Car 와 관련 있는 데이터와 메서드를 하나의 단위로 묶어서 코드의 가독성과 구조를 개선합니다.

코드리뷰중에 name과 distance의 무결성을 위해 #name, #distance의 사용과 get ,set을 통해 외부에서 함부로 수정되지 않도록 방지합니다.

class Car {
  constructor(name) {
    this.name = name;
    this.distance = DEFAULT_CAR_DISTANCE;
  }

  getName() {
    return this.name;
  }

  getDistance() {
    return this.distance;
  }

  setDistance(distance) {
    this.distance = distance;
  }

  move(randomNumber) {
    if (randomNumber >= MOVEMENT_MINIMUM) {
      this.setDistance(this.distance + MOVE_INCREMENT);
    }
  }

  getStringDistance() {
    var distanceString = "";
    for (let i = 0; i < this.distance; i++) {
      distanceString += "-";
    }
    return `${this.name} : ${distanceString}\n`;
  }
}

export default Car;

 


3.  MVC 패턴

MVC 패턴에서는 ModelController로 전달하여 필요한 데이터 처리를 수행합니다. Model은 애플리케이션의 데이터를 나타내며, Controller는 이 데이터를 가공하여 View에 표시하기 적합한 형태로 만듭니다.

 

class CarManager {
  constructor(carNameArr = []) {
    this.carNameArr = carNameArr.map((name) => new Car(name));
  }

  getCarNameArr() {
    return this.carNameArr;
  }

  moveCars() {
    this.carNameArr.forEach((car) => {
      const randomNumber = MissionUtils.Random.pickNumberInRange(0, 9);
      car.move(randomNumber);
    });
  }

  getEachStepResult() {
    let stepResult = "";
    this.carNameArr.forEach((car) => {
      stepResult += car.getStringDistance();
    });
    return stepResult;
  }

  getWinner() {
    let winners = [];
    const maxCar = this.carNameArr.reduce((prev, el) => {
      if (prev.getDistance() >= el.getDistance()) {
        return prev;
      } else {
        return el;
      }
    });
    this.carNameArr.forEach((car) => {
      if (car.getDistance() === maxCar.getDistance()) {
        winners.push(car.getName());
      }
    });

    return winners.join(", ");
  }
}

export default CarManager;

 


 

느낀점

Model, View, Controller를 분리하면 각 역할에 따라 코드 유지보수가 쉬워지고, 오류가 발생했을 때 원인을 찾기 편리합니다. 하지만 로직이 많아질수록 Controller가 과도하게 복잡해질 수 있다는 단점도 존재합니다.

 

클래스 정의를 통해 원하는 구조를 명확하게 설정하고 객체를 활용할 수 있었습니다. 이를 통해 코드의 재사용성과 확장성이 향상되어, 보다 유연한 개발이 가능해졌습니다.