✏️4.2 테스트할 샘플 코드

비즈니스 로직 코드

  • 생산자를 표현하는 Producer

  • 지역 전체를 표현하는 Province

JSON 데이터로부터 지역 정보를 읽어오는 코드

// Province 클래스
constructor(doc) {
  this.name = doc.name;
  this._producers = [];
  this._totalProduction = 0;
  this.demand = doc.demand;
  this._price = doc.price;
  doc.producers.forEach(d => this.addProducer(new Producer(this, d)));
}

addProducer(arg) {
  this._producers.push(arg);
  this._totalProduction += arg.production;
}

sampleProvinceData() 함수는 앞 생성자의 인수로 쓸 JSON 데이터를 생성한다. 이 함수를 테스트하려면 이 함수가 반환한 값을 인수로 넘겨서 Province 객체를 생성해보면 된다.

// 최상위
function sampleProvinceData() {
  return {
    name: "Asia",
    producers: [
      {name: "Byzantium", const: 10, production: 9},
      {name: "Attalia", const: 12, production: 10},
      {name: "Sinope", const: 10, production: 6},
    ],
    demane: 30,
    price: 20
  };
}
    

Province 클래스에는 다양한 데이터에 대한 접근자들이 담겨 있다.

// Province 클래스
get name() {
    return this._name;
  }

get producers() {
  return this._producers.slice();
}

get totalProduction() {
  return this._totalproduction;
}

set totalProduction(arg) {
  this._totalproduction = arg;
}

get demand() {
  return this._demand;
}

set demand(arg) {
  this._demand = parseInt(arg);
} // 숫자로 파싱해서 저장

get price() {
  return this._price;
}

set price(arg) {
  this._price = parseInt(arg);
} // 숫자로 파싱해서 저장

세터는 UI에서 입력한 숫자를 인수로 받는데, 이 값은 문자열로 전달된다. 계산에 활용하기 위해 숫자로 파싱한다.

Producer 클래스는 주로 단순한 데이터 저장소로 쓰인다.

class Producer {
  constructor(aProvince, data) {
    this._province = aProvince;
    this._cost = data.cost;
    this._name = data.name;
    this._production = data.production || 0;
  }

  get name() {
    return this._name;
  }

  get cost() {
    return this._cost;
  }

  set cost(arg) {
    this._cost = parseInt(arg);
  }

  get production() {
    return this._production;
  }

  set production(amountStr) {
    const amount = parseInt(amountStr);
    const newProduction = Number.isNaN(amount) ? 0 : amount;
    this._province.totalProduction += newProduction - this._production;
    this._production = newProduction;
  }
}

생산 부족분을 계산하는 코드

class Province {
  get shortfall() {
    return this._demand - this.totalProduction;
}

수익을 계산하는 코드

class Province {
  get profit() {
    return this.demandValue - this.demandCost;
  }
  get demandValue() {
    return this.satisfiedDemand * this.price;
  }
  get satisfiedDemand() {
    return Math.min(this._demand, this.totalProduction);
  }
  get demandCost() {
    let remainingDemand = this.demand;
    let result = 0;
    this.producers
      .sort((a, b) => a.cost - b.cost)
      .forEach(p => {
        const contribution = Math.min(remainingDemand, p.production);
        remainingDemand -= contribution;
        result += contribution * p.cost;
      });
    return result;
  }
}

Last updated