코드를 작성하다 보면, 임시로 필요한 데이터를 임시 변수에 할당해놓고 이후에 이 변수에 다시 접근해서 사용하는 경우가 많다. 이런 경우를 위한 리팩토링인데 책에서는 이런 변수를 함수 혹은 클래스의 메서드로 추출하라고 한다. 이렇게 하면, 중복되는 코드를 줄일 수 있다.
주의해야할 점이 있는데, 값이 매번 변하는 변수에 대해서는 이 리팩토링 기법을 적용하면 안된다. 값은 한 번만 대입한 뒤에 이후 로직에서는 읽기만 해야한다.
/**
* 임시 변수에 대해서 아예 함수로 만들어 버리는 리팩토링 기법이다.
*/
class Order {
constructor(quantity, item) {
this._quantity = quantity;
this._item = item;
}
get price() {
// 여기서의 임시 변수 basePrice, discountFactor에 대해 리팩토링을 해보자.
let basePrice = this._quantity * this._item.price;
let discountFactor = 0.98;
if (basePrice > 1000) discountFactor -= 0.03;
return basePrice * discountFactor;
}
}
// 먼저, 임시 변수를 immutable하게 const를 사용하자.
class Order {
// ...
get price() {
const basePrice = this.quantity * this._item.price;
let discountFactor = 0.98;
if (basePrice > 1000) discountFactor -= 0.03;
return basePrice * discountFactor;
}
}
// 대입문의 우변을 getter로 추출한다.
class Order {
// ...
get basePrice() {
this.quantity * this._item.price;
}
get price() {
const basePrice = this.basePrice;
let discountFactor = 0.98;
if (basePrice > 1000) discountFactor -= 0.03;
return basePrice * discountFactor;
}
}
// 변수를 인라인해주자.
class Order {
// ...
get basePrice() {
this.quantity * this._item.price;
}
get price() {
let discountFactor = 0.98;
if (this.basePrice > 1000) discountFactor -= 0.03;
return this.basePrice * discountFactor;
}
}
// discountFactor도 같은 방식으로 처리하자.
class Order {
// ...
get basePrice() {
this.quantity * this._item.price;
}
get discountFactor() {
let discountFactor = 0.98;
if (this.basePrice > 1000) discountFactor -= 0.03;
return discountFactor;
}
get price() {
return this.basePrice * this.discountFactor;
}
}
한번만 계산된 변수를 읽기 목적으로 하는 경우에만 쓰이는 리팩토링 기법이라서, 어능 상황에서 사용될지 아직은 와닿지가 않는다. 이 리팩토링의 목적은 변수를 계산하는 로직을 클라이언트에서 보이지 않도록 캡슐화하는 것에 있다고 생각한다.
Refactoring: Improving the Design of Existing Code (2nd Edition) p256-259.