수식의 결과를 저장하는 임시변수가 있을 땐,
그 수식을 빼내어 메서드로 만든 후, 임시변수 참조 부분을 전부 수식으로 교체하자
새로 만든 메서드는 다른 메서드에서도 호출 가능하다
특징
- 메서드 추출을 적용하기 전에 적용해야 한다
- 지역변수가 많을수록 메서드 추출이 힘들어지기 때문이다
- 임시변수를 메서드 호출로 수정하면 클래스 안 모든 메서드가 그 정보에 접근할 수 있다
- 적용하는 가장 간단한 상황은 임시변수에 값이 한번만 대입되고 대입문을 이루는 수식에 문제가 없을 때이다
방법
- 값이 한번만 대입되는 임시변수를 찾는다
- 값이 여러변 대입되는 임시변수가 있으면
임시변수 분리
를 적용한다
- 값이 여러변 대입되는 임시변수가 있으면
- 그 임시변수를 final로 선언한다
- 정말로 임시변수들이 값을 한번만 대입받는지 시험해볼수 있다
- 대입문 우변을 빼내어 메서드로 만든다
- 처음에는 private 으로 만들고, 나중에 더 여러곳에서 사용하게 되면 접근제한을 완화한다
- 추출 메서드에서 문제가 없는지(객체의 값을 변경한다거나) 확인한다
- 임시변수를 대상으로
임시변수 내용 직접 삽입
을 적용한다
예시
-
임시변수의 값을 루프를 돌면서 변경하는 경우가 많다
- 이럴떈 먼저 루프 자체를 메서드로 변경하고, 메서드 수행 결과를 임시변수에 담아 사용한다
- 이 임시변수를 전부 메서드 호출로 변경한다
- 여기서 성능이 느려질수도 있지만, 대체로 문제없다
- 리팩토링을 잘 할수록 더욱 강력한 최적화가 가능하기 때문이다
-
특정 로직의 메서드를 추출하려고 했는데 사용하는 임시변수가 많을 경우, 각 임시변수들에 대해 이 기법을 적용해나가면서 점진적으로 메서드를 분리해낼 수 있다
1
2
3
4
5
6
7
8
9
10
11int getPrice(){
int originalPrice = quantity * itemPrice; // 구매하고 싶은 개수 * 상품 가격
double discountFactor = 1.0;
if(originalPrice > 100000)
discountFactor = 0.8;
else if(originalPrice > 50000)
discountFactor = 0.9;
return originalPrice * discountFactor;
}이 상태에서 discountFactor 구하는 부분을 분리하려면 originalPrice가 전달되어야 하므로,
originalPrice 먼저 분리하고, 이 임시변수를 전부 메서드 호출로 변경한다1
2
3
4
5
6
7
8
9
10
11
12
13
14int getPrice(){
double discountFactor = 1.0;
if(getOriginalPrice() > 100000)
discountFactor = 0.8;
else if(getOriginalPrice() > 50000)
discountFactor = 0.9;
return getOriginalPrice() * discountFactor;
}
int getOriginalPrice(){
return quantity * itemPrice;
}이후 discountFactor 구하는 부분을 손쉽게 분리할 수 있다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16int getPrice(){
return getOriginalPrice() * getDiscountFactor();
}
int getDiscountFactor(){
if(getOriginalPrice() > 100000)
return 0.8;
else if(getOriginalPrice() > 50000)
return 0.9;
else
return 1.0;
}
int getOriginalPrice(){
return quantity * itemPrice;
}
참고 : 마틴 파울러, 『리팩토링』, 김지원 옮김, 한빛미디어(2012)