# 4.2 테스트할 샘플 코드

비즈니스 로직 코드

* 생산자를 표현하는 `Producer`
* 지역 전체를 표현하는 `Province`

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

```javascript
// 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 객체를 생성해보면 된다.

```javascript
// 최상위
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` 클래스에는 다양한 데이터에 대한 접근자들이 담겨 있다.

```javascript
// 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` 클래스는 주로 단순한 데이터 저장소로 쓰인다.

```js
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;
  }
}
```

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

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

수익을 계산하는 코드

```javascript
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;
  }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://koseoyoung.gitbook.io/library/refactoring/chapter04/4.2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
