본문 바로가기
JavaScript│Node js

마틴 파울러 리팩토링 Replace Query with Parameter

by 자유코딩 2020. 1. 2.

아래 코드를

targetTemperature(aPlan)

function targetTemperature(aPlan) {
    currentTemperature = thermostat.currentTemperature;
    // rest of function...
}

 

아래 코드로 바꿉니다.

targetTemperature(aPlan, thermostat.currentTemperature)

function targetTemperature(aPlan, currentTemperature) {
    // rest of function...
}

Replace Parameter with Query 를 반대로 합니다.

 

함수의 정의된 부분을 봤을 때 맨 위의 코드처럼 참조를 사용하는게 좋지 않을 때가 있습니다.

이건 보통 전역변수에 접근하려고 하거나 옮겨야 하는 변수에 접근 할때 그렇습니다.

이걸 해결하기 위해서 함수의 매개변수를 추가하고 내부의 참조를 제거합니다.

 

많은 경우에 이 리팩토링은 의존관계를 없애고 참조 무결성을 얻으려고 시행합니다.

 

Mechanics

1. Extract variable 을 시행한다.

2. Extract function을 시행한다.

3. Inline Variable 을 써서 만든 변수를 없앤다.

4. Inline function을 적용한다.

5. 함수의 이름을 바꾼다.

 

예제를 통해서 살펴봅니다.

class HeatingPlan {
    get targetTemperature() {
        if(thermost.selectedTemperature > this._max) return this._max;
        else if (thermost.selectedTemperature < this._min) return this._min;
        else return thermost.selectedTemperature; 
    }
    // caller
    if(thePlan.targetTemperature > thermost.currentTemperature) setToHeat();
    else if (thePlan.targetTemperature < thermost.currentTemperature) setToCool();
    else setOff();
}

 

먼저 코드를 아래 코드처럼 바꿉니다.

class HeatingPlan {
    get targetTemperature() {
        const selectedTemperature = thermost.selectedTemperature;
        if (selectedTemperature > this._max) return this._max;
        else if (selectedTemperature < this._min) return this._min;
        else return selectedTemperature;
    }
}

변수를 참조해서 사용하는 부분을 바꿨습니다.

 

그리고 extract function을 사용합니다.

 

class HeatingPlan {
    get targetTemperature() {
        const selectedTemperature = thermost.selectedTemperature;
        return this.xxNewtargetTemperature(selectedTemperature);
    }
    xxNewtargetTemperature(selectedTemperature) {
        if (selectedTemperature > this._max) return this._max;
        else if (selectedTemperature < this._min) return this._min;
        else return selectedTemperature;
    }
}

if~else if 부분을 다른 함수를 만들어서 넘겼습니다.

이제 inline variable 을 사용합니다.

get targetTemperature() {
        return this.xxNewtargetTemperature(thermost.selectedTemperature);
    }

Inline function도 사용합니다.

caller...
if(thePlan.xxNewtargetTemperature(thermost.selectedTemperature) > thermost.currentTemperature) setToHeat();
else if(thePlan.xxNewtargetTemperature(thermost.selectedTemperature) < thermost.currentTemperature) setToCool();
else setOff();
class HeatingPlan {
    targetTemperature(selectedTemperature) {
        if (selectedTemperature > this._max) return this._max;
        else if (selectedTemperature < this._min) return this._min;
        else return selectedTemperature;
    }
}

이렇게 리팩토링을 하면 함수의 호출 부분이 전보다 어색해 보일 수도 있습니다.

하지만 이렇게 하면 의존 관계를 개선할 수 있습니다.

 

이 리팩토링의 장점은 한가지 더 있습니다. 참조 무결성을 얻을 수 있습니다.

함수가 더이상 전역변수의 영향을 받지 않기 때문에 항상 같은 결과를 낼 수 있고 테스트하기 편리해집니다.

 

 

댓글