1. 중복코드(Duplicated Code)

[ 2017-07.05 작성 ]

한 클래스 내에 존재하는 중복 코드에 대해서는 중복된 부분을 하나의 메서드로 추출해야 한다. 서로 상관없는 두 클래스 안에 중복 코드가 있을 때는 클래스 추출이나 모듈 추출을 통해서 제 3의 클래시 (or 모듈)로 추출해야 한다.

한 곳 이상에서 중복된 코드 구조가 나타난다면, 그것을 합쳐서 프로그램을 개선할 수 있다.
  • 한 클래스의 서로 다른 두 메소드 안에 같은 코드가 있는 경우
  • Extract Method - 뽑아낸 메소드를 두 곳에서 호출하도록 하는 것
  • 동일한 수퍼 클래스를 갖는 두 서브 클래스에서 같은 코드가 있는 경우
  • 양쪽 클래스에서 Extract Method사용한 다음 Pull Up Method 사용한다
  • 코드가 비슷하기는 하지만 같지는 않다면 비슷한 부분과 서로 다른 부분을 분리하기 위해 Extract Method 사용 후 Form Template Method 사용할 수 있는지 살펴본다
  • 같은 작업을 하지만 다른 알고리즘을 사용한다면 두 알고리즘 중 더 명확한 것을 선택한 다음 Substitute Algorithm을 사용할 수 있다.
  • 서로 관계 없는 두 클래스에서 중복된 코드가 있는 경우 한쪽 클래스에서 Extract Class를 사용한 다음 양쪽에서 이 새로운 클래스를 사용하도록 하는 것 고려
  • 메소드가 클래스 중 하나에 포함되어 있고 다른 클래스에서 호출 세번째 클래스에 속하는 그 메소드가 원래 두 클래스에서 참조되어야 하는 경우

Extract Method (WikiDocs - https://wikidocs.net/608)
그룹으로 함께 묶을 수 있는 코드 조각이 있으면 코드의 목적이 잘 드러나도록 메소드의 이름을 지어 별도의 메소드로 뽑아낸다.

  • 메소드가 잘 쪼개져 있을 때 다른 메소드에서 사용될 확률이 높아진다
  • 수준(high-level)의 메소드를 볼 때 일련의 주석을 읽는 것 같은 느낌을 들도록 할 수 있다.

Form Template Method (http://www.javajigi.net/display/SWD/Form+Template+Method)

  • 한 상속 구조 내의 어떤 두 서브클래스가 유사한 단위 작업을 같은 순서로 실행하는 메서드를 각자 구현하고 있다면, 각 단위 작업을 별도의 메서드로 뽑아내어 두 메서드를 일반화하고 이렇게 일반화된 메서드를 수퍼클래스로 올려 템플릿 메서드로 만든다.
 private double GetPatternPrice()
 {
   double price;

  if ("TOMSONCUTEXT".Contains(this.Info.GoodsItem.Shape))
  {
   price = (this.width / 10d) * (this.height / 10d) * 400;
   if (price < 10000) { price = 10000; }
   price = price * (this.AdjustedUnit / 1000d);
  }
  else
  {
    price = (this.width / 10d) * (this.height / 10d) * 80;
    if (price < 5000) { price = 5000; }
    price = price * (this.AdjustedUnit / 1000d);
  }
  return price;
}

같은 코드가 있는 경우

private double GetPatternPrice()
{
   double price;

   if ("TOMSONCUTEXT".Contains(this.Info.GoodsItem.Shape))
   {
       price = 가로세로면적단가(400);
       if (price < 10000) { price = 10000; }
       price = 조정단위총가격(price);
  }
  else
  {
      price = 가로세로면적단가(80);
      if (price < 5000) { price = 5000; }
      price = 조정단위총가격(price);
  }
  return price;
}

public double 가로세로면적단가(int unitPrice)
{
  return (this.width / 10d) * (this.height / 10d) * unitPrice;
}

public double 조정단위총가격(double price)
{
  return price * (this.AdjustedUnit / 1000d);
}

Extract Method 메서드를 뽑아내어 다른 메서드에 호출하도록 하였습니다.

위에서 뽑아낼 코드들이 존재한다고 생각할 수 있습니다. 하지만 복잡도만 높아져 이해하기 어려운 문제가 발생할 수 있으니 과유불금은 금물입니다