복잡한 수식이 있는 경우에는,
수식의 결과나 또는 수식의 일부에 자신의 목적을 잘 설명하는 이름으로 된 임시변수를 사용하라.
동기
절차
quantity와 itemPrice의 곱이 basePrice라는 것을 알아낸 후 임시변수를 넣는다.
quantity와 itemPrice 의 곱은 코드의 뒷부분에서도 사용되므로 아래와 같이 바꾼다.
quantityDiscount 를 만든다.
shipping에 대해서도 같은 작업을 한다.
basePrice를 메소드로 뽑아낸다.
다른 부분도 계속 작업을 진행한다
Introduce Explaining Variable 은 언제 사용하는가? => Extract Method를 사용하기 어려울 때 이다.
if ( (platform.toUpperCase().indexOf("MAC") > -1) && (browser.toUpperCase().indexOf("IE") > -1) && wasInitialized() && resize > 0 ) { // do something }
final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1; final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1; final boolean wasResized = resize > 0; if (isMacOs && isIEBrowser && wasInitialized() && wasResized) { // do something }
동기
- 수식은 매우 복잡해져 알아보기 어려워질수가 있으므로 임시변수를 사용하여 수식을 좀 더 다루기 쉽게 한다.
- 조건문에서 각각의 조건의 뜻을 잘 설명하는 이름의 변수로 만들어 사용할 때 유용하다.
- 긴 알고리즘에서 각 단계의 계산 결과를 잘 지어진 이름의 임시변수로 설명할 수 잇다.
- 저자는 잘 사용하지 않는다고 한다.(머야 이게)
- 항상 Extract Method 를 사용한다.
- 이유: 임시변수는 한 메소드의 컨텍스트 내에서만 유용하지만 메소드는 객체의 모든 부분에서 뿐만 아니라 다른 객체에서도 유용하다.
- 지역변수 때문에 Extract Method 를 사용하기 어려운 경우에만 사용한다.
절차
- final 변수를 선언하고, 복잡한 수식의 일부를 이 변수에 대입한다.
- 원래의 복잡한 수식에서, 임시변수에 대입한 수식을 임시변수로 바꾼다.
- 컴파일과 테스트를 한다.
- 수식의 다른 부분에 대해서도 위의 작업을 반복한다.
예제
double price() { // price is base price - quantity discount + shipping return _quantity * _itemPrice - Math.max(0, _quantity - 500) * _itemPrice * 0.05 + Math.min(_quantity * _itemPrice * 0.1, 100.0); }
quantity와 itemPrice의 곱이 basePrice라는 것을 알아낸 후 임시변수를 넣는다.
double price() { // price is base price - quantity discount + shipping final double basePrice = _quantity * _itemPrice; return basePrice - Math.max(0, _quantity - 500) * _itemPrice * 0.05 + Math.min(_quantity * _itemPrice * 0.1, 100.0); }
quantity와 itemPrice 의 곱은 코드의 뒷부분에서도 사용되므로 아래와 같이 바꾼다.
double price() { // price is base price - quantity discount + shipping final double basePrice = _quantity * _itemPrice; return basePrice - Math.max(0, _quantity - 500) * _itemPrice * 0.05 + Math.min(basePrice * 0.1, 100.0); }
quantityDiscount 를 만든다.
double price() { // price is base price - quantity discount + shipping final double basePrice = _quantity * _itemPrice; final double quantityDiscount = Math.max(0, _quantity - 500) * _itemPrice * 0.05; return basePrice - quantityDiscount + Math.min(basePrice * 0.1, 100.0); }
shipping에 대해서도 같은 작업을 한다.
double price() { final double basePrice = _quantity * _itemPrice; final double quantityDiscount = Math.max(0, _quantity - 500) * _itemPrice * 0.05; final double shipping = Math.min(basePrice * 0.1, 100.0); return basePrice - quantityDiscount + shipping; }
예제(Extract Method를 사용한 경우)
원본 코드double price() { // price is base price - quantity discount + shipping return _quantity * _itemPrice - Math.max(0, _quantity - 500) * _itemPrice * 0.05 + Math.min(_quantity * _itemPrice * 0.1, 100.0); }
basePrice를 메소드로 뽑아낸다.
double price() { // price is base price - quantity discount + shipping return basePrice() - Math.max(0, _quantity - 500) * _itemPrice * 0.05 + Math.min(basePrice() * 0.1, 100.0); } private double basePrice() { return _quantity * _itemPrice; }
다른 부분도 계속 작업을 진행한다
double price() { return basePrice() - quantityDiscount() + shipping(); } private double quantityDiscount() { return Math.max(0, _quantity - 500) * _itemPrice * 0.05; } private double shipping() { return Math.min(basePrice() * 0.1, 100.0); } private double basePrice() { return _quantity * _itemPrice; }
Introduce Explaining Variable 은 언제 사용하는가? => Extract Method를 사용하기 어려울 때 이다.
- 수많은 지역변수를 사용하는 알고리즘.
- 꼬였던 로직이 좀 풀리면 Replace Temp with Query 를 적용한다.
- Replace Method with Method Object 를 사용하게 된다면 임시변수 또한 유용하다.
'프로그램언어 > Refactoring' 카테고리의 다른 글
실무에서 경험한 리팩토링 능력. (0) | 2011.02.09 |
---|---|
[ Refactoring ] Split Temporary Variable (2) | 2010.12.01 |
[ Refactoring ] Replace Temp with Query Method (0) | 2010.11.29 |
[ Refactoring ] Inline Temp (0) | 2010.11.24 |
[ Refactoring] Inline Method (0) | 2010.11.24 |