# 6.9 여러 함수를 클래스로 묶기 (Combine Functions into Class)

리팩터링 전

```javascript
function base(aReading) {...}
function taxableCharge(aReading) {...}
function calculateBaseCharge(aReading) {...}
```

리팩터링 후

```javascript
class Reading {
  base() {...}
  taxableCharge() {...}
  calculateBaseCharge() {...}
}
```

## 🧷 배경

공통 데이터를 중심으로 작동하는 함수 무리를 발견하면 클래스 하나로 묶는다. 이미 만들어진 함수를 재구성할 때는 물론, 새로 만든 클래스와 관련하여 놓친 연산을 찾아서 새 클래스의 메서드로 뽑아내는데도 좋다. 저자는 중첩 함수보다 클래스를 선호한다.

📍 클래스로 묶었을 때 장점

* 함수들이 공유하는 공통 환경을 더 명확하게 표현할 수 있다.
* 각 함수에 전달되는 인수를 줄여서 객체 안에서의 함수 호출을 간결하게 만들 수 있다.
* 객체를 시스템의 다른 부분에 전달하기 위한  참조를 제공할 수 있다.

## 🧷 절차

1. 함수들이 공유하는 공통 데이터 레코드를 캡슐화한다.
2. 공통 레코드를 사용하는 함수 각각을 새 클래스로 옮긴다.
3. 데이터를 조작하는 로직들은 함수로 추출해서 새 클래스로 옮긴다.

## 🧷 리팩터링 전

```javascript
reading = {customer: "ivan", quantity: 10, month: 5, year: 2017}
```

```javascript
// 클라이언트1
const aReading = acquireReading();
const baseCharge = baseRate(areadong.month, aReading.year) * aReading.quantity;

// 클라이언트2
const aReading = acquireReading();
const base = baseRate(areadong.month, aReading.year) * aReading.quantity;
const taxableCharge = Mtah.max(0, base - taxThreshole(aReading.year));

// 클라이언트3
const aReading = acquireReading();
const basicChargeAmount = calculateBaseCharge(aReading);

const calculateBaseCharge(aReading) {
  return baseRate(areadong.month, aReading.year) * aReading.quantity;
}
```

## 🧷 리팩터링 후

```javascript
class Reading {
  constructor(data) {
    this._customer = data.customer;
    this._quantity = data.quantity;
    this._month = data.month;
    this._year = data.year;
}  // 1. 레코드를 클래스로 변환하기 위해 레코드를 캡슐화한다.


get customer() { return this._custormer };
get quantity() { return this._quantity };
get month() { return this._month };
get year() { return this._year };

get baseCharge(aReading) {
  return baseRate(this.month, this.year) * this.quantity;
  }
}

get taxableCharge(aReading) {
  return Mtah.max(0, aReading.baseCharge - taxThreshole(aReading.year));
}

// 클라이언트1
const rawReading = acquireReading();
const aReading = new Reading(rawReading);
const baseCharge = aReading.baseCharge; // 중복된 계산 코드를 고쳐 앞의 메서드를 호출하게 한다.

// 클라이언트2
const rawReading = acquireReading();
const aReading = new Reading(rawReading);
const taxableCharge = Mtah.max(0, aReading.baseCharge - taxThreshole(aReading.year));

// 클라이언트3
const rawReading = acquireReading();
const aReading = new Reading(rawReading);
const taxableCharge = aReading.taxableCharge;
```


---

# 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/chapter06/6.9-combine-functions-into-class.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.
