원문 : Switch Statement code smell and polymorphism
위 글을 보면서 정리하고 있습니다.

switch-case 문을 사용한 소스코드를 보겠습니다.
[#M_ more.. | less.. |
public class Client {
  private double a;
  private double b;
  private double r;
  …
  public double calculateArea(int shape) {
      double area = 0;
      switch(shape) {
          case SQUARE:
              area = a * a;
              break;
          case RECTANGLE:
              area = a * b;
              break;
          case CIRCLE:
              area = Math.PI * r * r;
              break;
      }
      return area;
  }

  public double calculatePerimeter(int shape) {
      double perimeter = 0;
      switch(shape) {
          case SQUARE:
              perimeter = 4 * a;
              break;
          case RECTANGLE:
              perimeter = 2 * (a + b);
              break;
          case CIRCLE:
              perimeter = 2 * Math.PI * r;
              break;
      }
      return perimeter;
  }
  …
}
_M#]
위 코드를 보시면 swtich-case 문이 두 개의 메소드에서 중복이 되며 이것은 리팩토링이 필요하다는 것을 뜻합니다.

이 코드는 instanceOf 연산자를 사용해서 간추릴 수는 있지만 여전히 중복이 존재합니다. 이럴 때 다형성을 사용하려면 먼저 AbstractShape 클래스나 Shape라는 인터페이스를 만듭니다. 그리고 이를 구현 하거나 상속 받도록 구성합니다.

출처 : http://photos1.blogger.com/blogger/2606/2479/1600/ClassDiagram1.gif

위 UML 대로 코딩한 소스 코드는 다음과 같습니다.
[#M_ more.. | less.. |
Shape.java file
public interface Shape {
 
public double getArea();
  public double getPerimeter();
}

Square.java file
public class Square implements Shape {
  private double a;
  …
  public double getArea() {
      return a * a;
  }
  public double getPerimeter() {
      return 4 * a;
  }
}

Rectangle.java file
public class Rectangle implements Shape {
  private double a;
  private double b;
  …
  public double getArea() {
      return a * b;
  }
  public double getPerimeter() {
      return 2 * (a + b);
  }
}

Circle.java file
public class Circle implements Shape {
  private double r;
  …
  public double getArea() {
      return Math.PI * r * r;
  }
  public double getPerimeter() {
      return 2 * Math.PI * r;
  }
}
_M#]
이제 Client 코드에서는 switch 문이 사라집니다.

public class Client {
  private
Shape shape;
  …
  public double calculateArea() {
      return
shape.getArea();
  }
  public double calculatePerimeter() {
      return
shape.getPerimeter();
  }
}


Clinet의 코드가 처음 것에 비해 굉장히 단순해 졌으며 유연해 졌습니다. 새로운 도형이 추가 되어도 그 도형이 Shape 인터페이스만 구현했다면 이 코드는 수정될 필요가 없어졌습니다.

책임이라는 관점에서 살펴본다면 처음의 Client 코드는 도형의 세부 길이 까지 너무 많은 걸 알고 었는데 반해 여기서는 도형이 뭘 할 줄 아느냐만 (메소드만) 을 이용하고 있습니다.

인터페이스와, 다형성을 사용한 swich문의 중복과 coupling을 해결한 재밌는 글이였습니다.