logo
새로운 블로그로 이전하였습니다.

(리팩터링 2판) ch07.4 임시 변수를 질의 함수로 바꾸기

  • 리팩터링
  • 임시변수
  • 질의함수

✅ 배경

임시 변수의 쓰임새

  • 함수 안에서 어떤 코드의 결괏값을 뒤에서 다시 참조할 목적으로 임시 변수를 사용하기도 한다.
  • 임시 변수를 사용해 값을 계산하는 코드가 반복되는 것을 줄이고, 변수 이름으로 값의 의미를 설명할 수 있다.

임시 변수를 함수로 만들었을 때

  • 긴 함수의 한 부분을 별도 함수로 추출하고자 할 때 변수들을 각각의 함수로 만들면, 추출한 함수에 변수를 따로 전달할 필요가 없어 일이 수월해진다.
  • 추출한 함수와 원래 함수의 경계가 분명해져 부자연스러운 의존 관계나 부수효과를 찾는 데 도움이 된다.
  • 비슷한 계산을 수행하는 다른 함수에서도 사용할 수 있어 코드 중복이 개선된다.

예외

  • 값을 한 번만 계산하고, 후에는 읽기만 하는 것들은 질의 함수로 추출하면 안된다. (e.g) ‘옛날 주소’처럼 스냅샷 용도로 쓰이는 변수

✅ 절차

1. 변수가 사용되기 전에 값이 확실히 결정되는지, 
변수를 사용할 때마다 계산 로직이 매번 다른 결과를 내지는 않는지 확인한다.
2. 읽기전용으로 만들 수 있는 변수는 읽기전용으로 만든다.
3. 테스트한다.
4. 변수 대입문을 함수로 추출한다.
5. 테스트한다.
6. `변수 인라인하기`로 임시 변수를 제거한다.

🧑🏻‍🏭 리팩토링 실습

예시 코드

Order 클래스

constructor(quantity, item) {
	this._quantity = quantity;
	this._item = item;
}
 
get price() {
	var basePrice = this._quantity * this._item.price;
	var discountFactor = 0.98;
	
	if (basePrice > 1000) discountFactor -= 0.03;
	return basePrice * discountFactor;
}
  • 위와 같이 Order 클래스가 있다고 가정해보자.
  • 임시 변수인 basePricediscountFactor를 메서드로 바꿔보자.

🔧 basePrice 리팩토링

2. basePriceconst를 붙여 읽기 전용으로 만든다.

3. 그리고 테스트한다.

constructor(quantity, item) {
	this._quantity = quantity;
	this._item = item;
}
 
get price() {
	const basePrice = this._quantity * this._item.price; // <-- var를 const로 변경
	var discountFactor = 0.98;
	
	if (basePrice > 1000) discountFactor -= 0.03;
	return basePrice * discountFactor;
}

4. 대입문의 우변을 getter로 추출한다.

get price() {
	const basePrice = this.basePrice; // <--
	var discountFactor = 0.98;
	
	if (basePrice > 1000) discountFactor -= 0.03;
	return basePrice * discountFactor;
}
 
get basePrice() { // <--
	return this._quantity * this._item.price;
}

5. 테스트한다.

6. 변수를 인라인한다.

get price() {
    // const basePrice = this.basePrice 삭제
	var discountFactor = 0.98;
	if (this.basePrice > 1000) discountFactor -= 0.03; 
	return this.basePrice * discountFactor; 
}

🔧 discountFactor 리팩토링

  • basePrice와 같은 순서로 진행한다.

4. 함수를 추출한다.

get price() {
    const discountFactor = this.discountFactor;
    return this.basePrice * discountFactor;
}
 
get discountFactor() {
    var discountFactor = 0.98;
    if (this.basePrice > 1000) discountFactor -= 0.03;
    return discountFactor;
}

2. discountFactorconst를 붙여 읽기 전용으로 만든다.

6. 변수를 인라인한다.

get price() {
	return this.basePrice * this.discountFactor; // <--
}