Refactoring (리팩토링)

리팩토링(Refactoring) 3. Refactoring Techniques 1. Composing Methods

jw92 2021. 4. 6. 22:31

Refactoring Techniques 중 첫 번째로 Composoing Methods를 살펴본다.

 

Composing Methods

1. Extract Method

- Method로 그룹화 할 수 있는 code를 유의미한 이름과 함께 그룹화 하여 분리해라

- 기존

void printOwing(double amount) {
  printBanner(); // print details

  System.out.println("name:" + name);
  System.out.println("amount" + amount);
  }
  

- 수정

void printOwing(double amount) {
  printBanner();
  printDetails(amount);
}

void printDetails(double amount){
  System.out.println("name:" + name);
  System.out.println("amount" + amount);

}

2. Inline Method

 - Extract Method 의 반대

 - method의 body가 method 보다 더 명확한 의미를 가질 때, call을 하는 대신 method의 content로 사용해라

 - 기존

int getRating() {
  return (moreThanFiveLateDeliveries()) ? 2 : 1;
}

boolean moreThanFiveLateDeliveries() {
  return numberOfLateDeliveries > 5;
}

 - 수정

int getRating() {
  return (numberOfLateDeliveries > 5) ? 2 : 1;
}

3. Extract Variable

 - 이해하기 어려운 복잡한 expression을 설명이 가능한 변수로 분리해라.

 - 기존

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
}

4. Inline Temp

 - Extract Variable의 반대

 - 임시 변수가 간단한 연산의 결과이고 그것이 더 이상 아무 처리도 되지 않을 경우 expression 자체로 변경한다.

 - 기존

double basePrice = anOrder.basePrice();
return (basePrice > 1000) 

 - 수정

return (anOrder.BasePrice() > 1000)

5. Replace Temp with Query

 - temporary variable이 나중에 사용되기 위해 잠깐 값을 가지고 있는 것이라면 Method로 분리하라.

 - 기존

double basePrice = quantity * itemPrice;
if (basePrice > 1000)
  return basePrice * 0.95;
else
  return basePrice; 

 - 수정

if (basePrice() > 1000)
  return basePrice() * 0.95;
else
  return basePrice() * 0.98;
...

double basePrice() {
  return quantity * itemPrice;
}

6. Split Temporary Variable

 - temporary variable이 method 내에서 계산 중간 단계의 값을 가지는 경우, 각각의 값을 각각의 변수로 분리해라 ( 하나의 값이 하나의 책임을 가지도록 수정해라)

 - 기존

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); 

7. Remove Assignments To Parameters

 - method의 parameter로 할당된 값을 변경할 때는 parameter 대신 temporary variable를 사용해라

 - 기존

int discount (int inputVal, int Quantity, int yearToDate) {
  if (inputVal > 50)
    inputVal -= 2;
}

 - 수정

int descount ( int inputVal, int Quantity, int yearToDate) {
  int result = inputVal;
  if (inputVal > 50)
    result -= 2;
}

8. Replace Method with Method Object

 - local variable 끼리 얽혀있어 Extract Method가 안되는 경우, local variable이 하나의 field가 되도록 개별 클래스로 분리해라

 - 기존

class Order ...
  double price() {
    double primaryBasePrice;
    double secondaryBasePrice;
    double teriaryBasePrice;
    // long computation;
    ...
}
...

 - 수정

class Order ...
public double price() {
  return new PriceCalculator(this).compute();
  }
}
class PriceCalculator {
  private double primaryBasePrice;
  private double secondaryBasePrice;
  private double tertiaryBasePrice;
  public PriceCalculator(Order order) {
  // copy relevant information from order object.
  ...
}
public double compute() {
  // long computation.
  ...
  }
}

9. Substitute Algorithm

 - 현재의 알고리즘을 더 나은 알고리즘으로 바꾼다.

 - 기존

String foundPerson(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 "";
}

 - 수정

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