템플릿 메소드 패턴

템플릿 메소드 패턴은 알고리즘을 캡슐화 한다. 이해가 안되니 아래를 보자.

Coffee와 Tea를 만드는 클래스가 있다. make()는 일련의 메소드를 모아 각 음료를 만드는 함수이다.

public class Coffee {
 void make() {
  hotWater();
  putCoffee();
  putCup();
  putSugar();
 }
 public void hotWater{
  // 물을 끓인다.
 }
 public void putCoffee{
  // 커피를 넣는다.
 }
 public void putCup{
  // 커피를 컵에 넣는다
 }
 public void putSugar{
  // 설탕을 넣는다.
 }
}

public class Tea {
 void make() {
  hotWater();
  putTea();
  putCup();
  putLemon();
 }
 public void hotWater{
  // 물을 끓인다.
 }
 public void putTea{
  // 차를 넣는다.
 }
 public void putCup{
  // 차를 컵에 넣는다
 }
 public void putLemon{
  // 레몬을 넣는다.
 }
}

Coffee와 Tea 메소드를 보니 코드가 중복되는 부분이 있으며, 일단 코드에 중복이 있을 경우 디자인을 고쳐야 하지 않을까 라는 생각이 필요하다.

Beberage(음료)라는 상위 클래스를 만들었다. make 메소드는 서브 클래스마다 다르므로 추상 메소드로 선언한다. hotwater, putCup 메소드는 서브클래스로 공통으로 쓰기때문에 부모 클래스에 정의하였다.  Coffee, Tea 클래스는 make 메소드를 내부에서 정의하고 알고리즘의 다른 부분들(putCoffee, putTea / putSugar, putLemon)은 서브클래스 내부에서 정의 하였다.

위의 다이어그램을 다시 생각해보자. 사실 putCoffe와 putTea는 만드는 과정 중 뜨거운 물에 넣는다는 의미에서 같은 맥락이고, addSugar, addLemon는 만들어진 음료 위에 무엇을 넣는것에서 같은 맥락이다.
따라서 putCoffee와 putTea를 putSomething, addSugar, addLemon을 addItem 으로 대체해보자. (조금 어거지다)


public class Beverage {
 final void make() {
  hotWater();
  putSomething();
  putCup();
  addItem();
 }
 abstract void putSomething();
 abstract void addItem();
 
 void hotWater{
  // 물을 끓인다.
 }
 void putCup{
  // 커피를 컵에 넣는다
 }
}

public class Coffee extends Beverage{
 public void putSomething{
  // 커피를 넣는다.
 }
 public void addItem{
  // 설탕을 넣는다.
 }
}

public class Tea {
 public void putSomething{
  // 차를 넣는다.
 }
 public void addItem{
  // 레몬을 넣는다.
 }
}

지금까지 한 것이 템플릿 메소드 패턴이라 할 수 있다.
Beverage의 make가 캡슐화된 알고리즘이 되며, 템플릿 메소드에서는 알고리즘의 각 단계들을 정의하며 한 개 이상의 알고리즘 단계가 서브클래스에 의해 제공될 수 있다.

처음 만든 클래스와 템플릿 메소드를 사용한 경우를 비교하면 아래표와 같다.























댓글 없음:

댓글 쓰기