본문 바로가기

프로그램언어/Refactoring

[ Refactoring ] Split Temporary Variable

루프 안에 있는 변수나 collecting temporary variable도 아닌 임시 변수에 값을 여러 번 대입하는 경우에는, 각각의 대입에 대해서 따로따로 임시변수를 만들어라.

double temp = 2 * (_height + _width);
     System.out.println (temp);
     temp = _height * _width;
     System.out.println (temp);
final double perimeter = 2 * (_height + _width);
     System.out.println (perimeter);     
     final double area = _height * _width;       
     System.out.println (area);

 * collecting temporary variable => (for(int i=0; i<10; i++))

동기

  • 임시변수가 여러 번 설정된다면 그 변수는 메소드 안에서 여러가지 용도로 사용되고 있다는 뜻이다.
  • 어떤 변수든 여러 가지 용도로 사용되는 경우에는 각각의 용도에 대해 따로 변수를 사용하도록 바꾸어야 한다. => 가독성 X

절차

  • 임시변수가 처음 선언된 곳과 임시변수에 값이 처음 대입된 곳에서 변수의 이름을 바꾼다. => collecting temporary variable 은 분리하면 안된다.
  • 새로 만든 임시변수를 final 로 선언한다.
  • 임시변수에 두 번째로 대입하는 곳의 직전까지 원래 임시변수를 참조하는 곳을 모두 바꾼다.
  • 임시변수에 두 번째로 대입하는 곳에서 변수를 선언한다.
  • 컴파일과 테스트를 한다.
  • 각 단계(임시변수가 선언되는 곳에서부터 시작하여)를 반복한다. 그리고 임시변수에 다음으로 대입하는 곳까지 참조를 바꾼다.

예제

해기스(haggis:스코틀랜드 요리)가 이동한 거리를 계산하는 코드.

double getDistanceTravelled (int time) {
      double result;
      double acc = _primaryForce / _mass; 
      int primaryTime = Math.min(time, _delay);
      result = 0.5 * acc * primaryTime * primaryTime;
      int secondaryTime = time - _delay;
      if (secondaryTime > 0) {
          double primaryVel = acc * _delay;
          acc = (_primaryForce + _secondaryForce) / _mass;
          result +=  primaryVel * secondaryTime + 0.5 * acc * secondaryTime * secondaryTime;
      }
      return result;
  }

* acc 값이 두번 설정된다. 즉 두가지 용도로 사용된다는 뜻.

임시변수 이름을 바꾸고, 바꾼 변수를 final 로 선언한다.(값이 한번만 설정되는지 확인하기 위해) 해당 임시변수를 참조하는 곳은 모두 수정한다. 두 번째로 값을 대입하는 부분에는 다시 선언한다.


double getDistanceTravelled (int time) {
        double result;
           final   double primaryAcc  = _primaryForce / _mass;        
           int primaryTime = Math.min(time, _delay);
           result = 0.5 * primaryAcc * primaryTime * primaryTime;
           int secondaryTime = time - _delay;
        if (secondaryTime > 0) {
           double primaryVel = primaryAcc * _delay;
           double acc = (_primaryForce + _secondaryForce) / _mass;
           result +=  primaryVel * secondaryTime + 0.5 * acc * secondaryTime * secondaryTime;
        }
        return result;
    }


두 번째 대입에 임시변수의 새로운 이름을 지정하고 원래의 임시변수 이름을 완전히 제거한다.

double getDistanceTravelled (int time) {
       double result;
       final double primaryAcc = _primaryForce / _mass;
       int primaryTime = Math.min(time, _delay);
       result = 0.5 * primaryAcc * primaryTime * primaryTime;
       int secondaryTime = time - _delay;
       if (secondaryTime > 0) {
           double primaryVel = primaryAcc * _delay;
           final double secondaryAcc = (_primaryForce + _secondaryForce) / _mass;           
           result +=  primaryVel * secondaryTime + 0.5 * secondaryAcc * secondaryTime * secondaryTime;
       }
       return result;
   }