블로그 이미지
암초보

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

Tag

01-27 13:02
2011. 9. 19. 04:04 프로그래밍/Refactoring

※ 알고리즘을 보다 명확한 것으로 바꾸고 싶을 때는, 메소드의 몸체를 새로운 알고리즘으로 바꾼다.

※ 절차
1. 대체 알고리즘을 준비하여 적용후 컴파일
2. 알고리즘 테스트. 만약 결과가 같다면 작업은 끝
3. 만약 결과가 같지 않다면, 테스트에서 비교하기 위해 예전의 알고리즘을 사용하여 디버깅

Before
String findPerson(String[] people) {
  for (int i=0; i<people.length; i++) {
    if(people[i].equals("Don")) {
      return "Don";
    }
    if(people[i].equals("John")) {
      return "John";
    }
    if(people[i].equals("Kent")) {
      return "Kent";
    }
  }
  return " ";
}


After
String findPerson(String[] people) {
  List candidates = Arrays.asList(new String[] {"Don", "John", "Kent"});
  for (int i=0; i<people.length; i++) {
    if(candidates.contains(people[i]))
      return people[i];
  }
  return " ";
}



//////////////////////////////////////////////////////////////////////////////////////////
출처 : 마틴 파울러의 리펙토링
//////////////////////////////////////////////////////////////////////////////////////////

'프로그래밍 > Refactoring' 카테고리의 다른 글

Replace Method with Method Object  (0) 2011.09.19
Remove Assignments to Parameters  (0) 2011.09.19
Split Temporary Variable  (0) 2011.09.19
Introduce Explaining Variable  (0) 2011.09.19
Replace Temp with Query  (0) 2011.09.19
posted by 암초보
2011. 9. 19. 03:52 프로그래밍/Refactoring
※ 긴 메소드가 있는데, 지역변수 때문에 Extract Method를 적용할 수 없는 경우에는,
메소드를 그 자신을 위한 객체로 바꿔서 모든 지역변수가 그 객체의 필드가 되도록 한다. 이렇게 하면 메소드를 같은 객체 안의 여러 메소드로 분해할 수 있다.

※ 절차
1. 메소드의 이름을 따서 새로운 클래스를 생성
2. 새로운 클래스에 원래 메소드가 있던 객체(소스 객체)를 보관하기 위한 final 필드를 하나 만들고, 메소드에서 사용되는 임시변수와 파라미터를 위한 필드를 만든다.
3. 새로운 클래스에 소스 객체와 파라미터를 취하는 생성자를 만든다.
4. 새로운 클래스에 compute라는 이름의 메소드를 만든다.
5. 원래의 메소드를 compute 메소드로 복사한다. 원래의 객체에 있는 메소드를 사용하는 경우에는 소스 객체 필드를 사용하도록 바꾼다.
6. 컴파일한다.
7. 새로운 클래스의 객체를 만들고 원래의 메소드를 새로 만든 객체의 compute 메소드를 호출하도록 바꾼다.
8. 지역변수가 모두 필드로 빠뀌었으므로, 파라미터를 넘길 필요 없이 마음대로 메소드를 분해할 수 있다.


Before
 class Account ....
   int gamma (int inputVal, int quantity, int yearToDate) {
      int importantValue1 = (inputVal * quantity) + delta();
      int importantValue2 = (inputVal * yearToDate) + 100;
      if ((yearToDate - importantValue1) > 100)
         importantValue2 -= 20;
      int importantValue3 = importantValue2 * 7;
      // 기타 등등
      return importantValue3 - 2 * importantValue1;
   }

After
 class Gamma ...
   private final Account _account;
   private int inputVal;
   private int quantity;
   private int yearToDate;
   private int importantValue1;
   private int importantValue2;
   private int importantValue3;
   Gamma(Account source, int inputValArg, int quantityArg, int yearToDateArg) {
      _account = source;
      inputVal = inputValArg;
      quantity = quantityArg;
      yearToDate = yearToDateArg;
   }
   int compute() {
      int importantValue1 = (inputVal * quantity) + _account.delta();
      int importantValue2 = (inputVal * yearToDate) + 100;
      if ((yearToDate - importantValue1) > 100)
         importantValue2 -= 20;
      int importantValue3 = importantValue2 * 7;
      // 기타 등등
      return importantValue3 - 2 * importantValue1;

   }
class Account ....
   int gamma (int inputVal, int quantity, int yearToDate) {
     return new Gamma(this, inputVal, yearToDate).compute(); 
   }


※ compute 메소드에서 파라미터를 넘겨주는 것에 대한 걱정 없이 쉽게 Extract Method를 사용할 수 있다.




//////////////////////////////////////////////////////////////////////////////////////////
출처 : 마틴 파울러의 리팩토링
//////////////////////////////////////////////////////////////////////////////////////////

'프로그래밍 > Refactoring' 카테고리의 다른 글

Substitute Algorithm  (1) 2011.09.19
Remove Assignments to Parameters  (0) 2011.09.19
Split Temporary Variable  (0) 2011.09.19
Introduce Explaining Variable  (0) 2011.09.19
Replace Temp with Query  (0) 2011.09.19
posted by 암초보
2011. 9. 19. 03:32 프로그래밍/Refactoring
※ 파라미터에 값을 대입하는 코드가 있으면, 대신 임시변수를 사용하도록 하라.

※ 자바에서는 값에 의한 전달만 사용, 참조에 의한 전달은 사용 안함

※ 절차
1. 파라미터를 위한 임시변수를 만든다.
2. 파라미터에 값을 대입한 코드 이후에서 파라미터에 대한 참조를 임시변수로 바꾼다.
3. 파라미터에 대입하는 값을 임시변수에 대입하도록 바꾼다.
4. 컴파일 및 테스트

Before
int discount (int inputVal, int quantity, int yearToDate) {
   if (inputVal > 50) inputVal -= 2;
   if (quantity > 100) inputVal -= 1;
   if (yearToDate > 10000) inputVal -= 4;
   return inputVal;
}

After
int discount (int inputVal, int quantity, int yearToDate) {
   int result = inputVal;
   if (inputVal > 50) result -= 2;
   if (quantity > 100) result -= 1;
   if (yearToDate > 10000) result -= 4;
   return result;
}

More....
파라미터를 final로 선언하여 이 관례를 강제할 수 있지만,
(자바 1.1부터 파라미터를 fianl로 하는 것이 가능해짐)
짧은 메소드에 대해서는 코드를 명확하게 하는데 별로 큰도움이 되지 않으므로 사용 안함.
int discount (final int inputVal, final int quantity, final int yearToDate) {
   int result = inputVal;
   if (inputVal > 50) result -= 2;
   if (quantity > 100) result -= 1;
   if (yearToDate > 10000) result -= 4;
   return result;
}




//////////////////////////////////////////////////////////////////////////////////////////
출처 : 마틴 파울러의 리팩토링
//////////////////////////////////////////////////////////////////////////////////////////

'프로그래밍 > Refactoring' 카테고리의 다른 글

Substitute Algorithm  (1) 2011.09.19
Replace Method with Method Object  (0) 2011.09.19
Split Temporary Variable  (0) 2011.09.19
Introduce Explaining Variable  (0) 2011.09.19
Replace Temp with Query  (0) 2011.09.19
posted by 암초보