같든 도출 로직이 반복되는 경우 변환 함수를 사용하여 도출작업을 한데 모아 검색과 갱신을 일관된 장소에서 처리하고 로직 중복을 막는다. 변환함수는 원본 데이터를 입력 받아서 필요한 정보를 모두 도출한 뒤, 각각을 출력 데이터 필드에 넣어 반환한다. 도출 과정을 검토할 때 변환 함수만 살펴보면 된다.
📍 클래스 묶기 VS 변환 함수로 묶기
원본 데이터가 코드 안에서 갱신 될 때는 → 클래스로 묶기
도출 로직의 중복을 피하고 싶은 경우 → 변환 함수로 묶기
🧷 절차
변환할 레코드를 입력받아서 값을 그대로 반환하는 변환 함수를 만든다.
묶을 함수 중 함수 하나를 골라서 본문 코드를 변환 함수로 옮기고, 처리 결과를 레코드에 새 필드로 기록한다. 그런 다음 클라이언트 코드가 이 필드를 사용하도록 수정한다.
테스트한다.
나머지 관련 함수도 위 과정에 따라 처리한다.
🧷 리팩터링 전
// 클라이언트 1
const aReading = acquireReading();
const baseCharge = baseRate(aReading.month, aReading.year) * aReading.quantity;
// 클라이언트 2
const aReading = acquireReading();
const base = (baseRate(aReading.month, aReading.year) * aReading.quantity);
const taxableCharge = Math.max(0, base = taxThreshold(aReading.year)); // 중복 코드는 나중에 로직을 수정할 때 힘들다. (반드시 수정할 일이 생긴다.)
// 클라이언트 3
const aReading = acquireReading();
const basicChargeAmount = calculateBaseCharge(aReading);
function calculateBaseCharge(aReading) {
return baseRate(aReading.month, aReading.year) * aReading.quantity);
}
🧷 리팩터링 후
function enrichReading(original) {
const result = _.cloneDeep(original) // lodash cloneDeep
result.baseCharge = calculateBaseCharge(result);
result.taxableCharge = Mtah.max(0, aReading.baseCharge - taxThreshole(aReading.year));
return result
}
const rawReading = acquireReading();
const aReading = enrichReading(rawReading);
const base = aReading.baseCharge;
const taxableCharge = aReading.tadableCharge;