리팩터링 (6장 기본적인 리팩토링 -2)

박주진·2021년 10월 12일
0

리팩터링

목록 보기
4/7

아래 내용은 리팩터링 2판 내용과 한달한권 읽기 강의를 기반하여 정리한 글입니다.

여러 함수를 클래스로 묶기

  • 목적이 같은 데이터를 사용하는 함수를 한 클래스로 묶는 방법 여러함수를 변환 함수로 묶기와 동일
  • 방법은 연관된 데이터를 다루는 함수와 데이터를 가진 객체를 리턴(OOP).
  • 데이터와 데이터를 처리하는 함수는 가까이 있어야 좋다. 가장 가까이 두는 방법으로는 데이터 클래스를 일반 클래스로 만들고 처리 함수를 클래스 내부로 옮기는 것이다.
  • 현재 프로젝트에 반영된 프로그램이 스타일에 따라 여러함수를 변환 함수로 묶기(fp) 또는 여러 함수를 클래스로 묶기(oop) 를 선택해라.
  • 장점
    • 함수들이 공유하는 공통환경이 더 명확해 진다.(공통환경이란 함수마다 공유하는 개념 또는 데이터들 인가?)
    • 함수에 전달되는 인수를 줄이고 객체 안에서 함수 호출을 간결하게 만들 수 있다.(복잡한 데이터 처리 로직을 객체안으로 숨겨 간결하게 만든다는 뜻?)
    • 객체를 시스템에 다른 부분에 전달하기 위한 참조를 제공 가능하다. (데이터 클래스는 참조 전달이 불가능 한가?)
//전
const aReading = acquireReading();
const base = (baseRate(aReading.month, aReading.year) * aReading.quantity);
const taxableCharge = Math.max(0, base=taxThreshold(aReading.year));
const basicChargeAmount = calculateBaseCharge(aReading);

// 함수로 추출되어 있지만 못 보고 지나치기 쉽상이다.
fucntion calculateBaseCharge(aReading) {
 return baseRate(aReading.month, aReading.year) * aReading.quantity;
}

// 후
const aReading = acquireReading();
const base = aReading.baseCharge;
const taxableCharge = aReading.taxableCharge
const basicChargeAmount = aReading.baseCharge;

class Reading {

get baseCharge() {
// 생략 내용은 위에 코드랑 동일
}

get taxableCharge() {
// 생략 내용은 위에 코드랑 동일
}

}

활용될 수 있는 악취들

  • 가변 데이터
  • 산탄총 수술

여러함수를 변환 함수로 묶기

  • 변환 함수란 원본 데이터를 입력받아서 필요한 정보를 모두 도출한 뒤, 각각을 출력 데이터의 필드에 넣어 반환하는 하는 함수 이다.
  • 목적은 연관된 데이터를 다루는 함수들을 하나로 묶는것 이는 여러 함수를 클래스로 묶기와 동일하다.
  • 여러 함수를 모아 실행 결과 값을 하나로 모은 객체로 리턴 (FP).
  • 현재 프로젝트에 반영된 프로그램이 스타일에 따라 여러함수를 변환 함수로 묶기(FP) 또는 여러 함수를 클래스로 묶기(OOP
    )
    를 선택해라.
//전
const aReading = acquireReading();
const base = (baseRate(aReading.month, aReading.year) * aReading.quantity);
const taxableCharge = Math.max(0, base=taxThreshold(aReading.year));
const basicChargeAmount = calculateBaseCharge(aReading);

// 함수로 추출되어 있지만 못 보고 지나치기 쉽상이다.
fucntion calculateBaseCharge(aReading) {
 return baseRate(aReading.month, aReading.year) * aReading.quantity;
}

// 후
const rawReading = acquireReading();
const aReading = enrichReading(rawReading);
const base = aReading.baseCharge;
const taxableCharge = aReading.taxableCharge
const basicChargeAmount = aReading.baseCharge;

function enrichReading(original) {
 const result = _.cloneDeep(original);
 result.baseCharge = caculateBaseCharge(result);
 result.taxableCharge = Math.max(0, base=taxThreshold(aReading.year));
 
  fucntion calculateBaseCharge(aReading) {
   return baseRate(aReading.month, aReading.year) * aReading.quantity;
  }
}

활용될 수 있는 악취들

  • 가변 데이터
  • 산탄총 수술

단계 쪼개기

  • 서로 다른 두 대상을 한꺼번에 다루는 코드는 각각의 별개 모듈로 분리하라. (즉 한 함수 내부에서 서로 다른 데이터와 함수를 사용하여 여려가지 일을 하는 코드를 한 가지 일씩 분리하라 는 뜻인가? )
  • 모듈이 잘 분리되면 수정시 다른 모듈의 상세 내용을 이해하지 않고도 수정이 가능하다.
//전
const orderRecord = orderString.split(/\s+/);
const productPrice = priceList[orderData[0].split("-")[1]];
const orderPrice = parseInt(orderData[1]) * productPrice; 

//후
const orderRecord = parseOrder(order);
const orderPrice = price(orderRecord, priceList);

function parseOrder(aString) {
	const values = aString.split(/\s+/);
  return ({
      productID: values[0].split("-")[1],
      quantity: parseInt(values[1]),
  })
}

function price(order, priceList) {
	return order.quantity * priceList[order.productID];
}

활용될 수 있는 악취들

  • 데이터 클래스 (단계 쪼개기의 결과로 나온 중간 데이터는 예외?)
  • 뒤엉킨 변경
  • 산탄총 수술

의문

  • 긴함수 는 왜 적용 될 수 없는 기법인가??

0개의 댓글