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

리팩터링 전

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

리팩터링 후

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

🧷 배경

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

📍 클래스로 묶었을 때 장점

  • 함수들이 공유하는 공통 환경을 더 명확하게 표현할 수 있다.

  • 각 함수에 전달되는 인수를 줄여서 객체 안에서의 함수 호출을 간결하게 만들 수 있다.

  • 객체를 시스템의 다른 부분에 전달하기 위한 참조를 제공할 수 있다.

🧷 절차

  1. 함수들이 공유하는 공통 데이터 레코드를 캡슐화한다.

  2. 공통 레코드를 사용하는 함수 각각을 새 클래스로 옮긴다.

  3. 데이터를 조작하는 로직들은 함수로 추출해서 새 클래스로 옮긴다.

🧷 리팩터링 전

reading = {customer: "ivan", quantity: 10, month: 5, year: 2017}
// 클라이언트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;
}

🧷 리팩터링 후

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;

Last updated