임시변수를 메서드 호출로 전환

수식의 결과를 저장하는 임시변수가 있을 땐,
그 수식을 빼내어 메서드로 만든 후, 임시변수 참조 부분을 전부 수식으로 교체하자
새로 만든 메서드는 다른 메서드에서도 호출 가능하다

특징

  • 메서드 추출을 적용하기 전에 적용해야 한다
    • 지역변수가 많을수록 메서드 추출이 힘들어지기 때문이다
  • 임시변수를 메서드 호출로 수정하면 클래스 안 모든 메서드가 그 정보에 접근할 수 있다
  • 적용하는 가장 간단한 상황은 임시변수에 값이 한번만 대입되고 대입문을 이루는 수식에 문제가 없을 때이다

방법

  1. 값이 한번만 대입되는 임시변수를 찾는다
    • 값이 여러변 대입되는 임시변수가 있으면 임시변수 분리를 적용한다
  2. 그 임시변수를 final로 선언한다
    • 정말로 임시변수들이 값을 한번만 대입받는지 시험해볼수 있다
  3. 대입문 우변을 빼내어 메서드로 만든다
    • 처음에는 private 으로 만들고, 나중에 더 여러곳에서 사용하게 되면 접근제한을 완화한다
    • 추출 메서드에서 문제가 없는지(객체의 값을 변경한다거나) 확인한다
  4. 임시변수를 대상으로 임시변수 내용 직접 삽입을 적용한다

예시

  • 임시변수의 값을 루프를 돌면서 변경하는 경우가 많다

    • 이럴떈 먼저 루프 자체를 메서드로 변경하고, 메서드 수행 결과를 임시변수에 담아 사용한다
    • 이 임시변수를 전부 메서드 호출로 변경한다
      • 여기서 성능이 느려질수도 있지만, 대체로 문제없다
      • 리팩토링을 잘 할수록 더욱 강력한 최적화가 가능하기 때문이다
  • 특정 로직의 메서드를 추출하려고 했는데 사용하는 임시변수가 많을 경우, 각 임시변수들에 대해 이 기법을 적용해나가면서 점진적으로 메서드를 분리해낼 수 있다

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int 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
    14
    int 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
    16
    int 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)