Template Method Pattern

윤세영·2023년 7월 6일
0

DesignPattern

목록 보기
6/15

정의

  • 상위 class에서 처리의 흐름을 제어하고, 하위class에서 처리의 내용을 구체화 한다.
  • 여러 class에서 공통되는 사항은 상위 추상 class에서 구현하고, 각각의 세부내용은 하위 class에서 구현한다.
  • 그 결과 코드의 중복을 줄이고, Refactoring에 유리한 패턴으로 상속을 통한 확장 개발 방법으로 Strategy Pattern과 함께 많이 사용되는 pattern이다.
Hook method
  • 필수적이지 않은 부분으로 필요에 따라 선택적으로 sub-class에서 구현할 경우 사용한다.
  • Abstract class에서 정의된 어떠한 행도 하지 않을 수 있고, sub-class의 공통된 동작을 할 수도 있다.
  • 또한, sub-class에서 hook method를 재정의 하여 사용하는 방법도 있다.
  • Sub-class에 따라 algorithm에 원하는 내용을 추가할 수 있도록 하는 것이 hook-method의 존재 이유다.
요구사항
  • 멤버 함수들의 접근 범위 지정을 명확히 한다.
  • 가상함수, 일반함수로 선언 하는 것 에 대한 기준이 필요
  • Virtual 함수의 수를 최소화한다.
Hollywood Principle
  • Sub-class는 upper-class에 구성요소로써 활용될 수 있지만, sub-class가 upper-class를 호출하여 자신을 호출하게 하면 안된다는 것이다.
  • Template Method Pattern에서도 이러한 원칙을 따르고 있는데,
    설명을 더하면, abstract class에서는 sub-class에 있는 기능을 호출할 수 있지만,
    sub-class에서는 abstract-class의 template method를 호출하거나 수정할 수 없다는 것이다.

장점

  • 상위위 class의 template method에서 알고리즘이 기술되어 있으므로,
  • 하위 class에서는 알고리즘을 일일이 기술할 필요가 없다.

소스코드

  • 상위클래스
public abstract class CaffeineBeverageWithHook {

         void prepareRecipe(){

                 boilWater();

                 brew();

                 pourInCup();

                 if(customerWantsCondiments()){
                          addCondiments();
                 }
         }


         abstract void brew();

         abstract void addCondiments();

         void boilWater(){
                 System.out.println("Boiling water");
         }

         void pourInCup(){
                 System.out.println("Pouring into cup");
         }

         boolean customerWantsCondiments(){
                 return true;
         }
}
  • 하위클래스(coffee)
public class CoffeeWithHook extends CaffeineBeverageWithHook{
         @Override
         void brew() {
                 // TODO Auto-generated method stub
                 System.out.println("Dripping Coffee through filter");
         }
 
         @Override
         void addCondiments() {
                 // TODO Auto-generated method stub
                 System.out.println("Adding Sugar and Milk");
         }
         @Override
         public boolean customerWantsCondiments() {
                 // TODO Auto-generated method stub
                 String answer = getUserInput();
 
                 if(answer.toLowerCase().startsWith("y")){
                          return true;
                 }else{
                          return false;
                 }
         }
 
         private String getUserInput(){
                 String answer = null;
 
                 System.out.println("would you like milk&sugar with your coffee (y/n) ?");
                 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
 
                 try {
                          answer = in.readLine();
                 } catch (Exception e) {
                          // TODO: handle exception1
                          System.err.println("IO error trying to read your answer");
                 }
 
                 if(answer==null){
                          return "no";
                 }
                 return answer;
         }
}
  • 하위클래스(tea)
public class TeaWithHook extends CaffeineBeverageWithHook{
 
         @Override
         void brew() {
                 // TODO Auto-generated method stub
                 System.out.println("Steeping the tea");
         }
 
         @Override
         void addCondiments() {
                 // TODO Auto-generated method stub
                 System.out.println("Adding Lemon");
         }
         @Override
         public boolean customerWantsCondiments() {
                 // TODO Auto-generated method stub
                 String answer = getUserInput();
 
                 if(answer.toLowerCase().startsWith("y")){
                          return true;
                 }else{
                          return false;
                 }
         }
 
         private String getUserInput(){
                 String answer = null;
 
                 System.out.println("would you like lemon with your tea (y/n) ?");
                 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
 
                 try {
                          answer = in.readLine();
                 } catch (Exception e) {
                          // TODO: handle exception1
                          System.err.println("IO error trying to read your answer");
                 }
 
                 if(answer==null){
                          return "no";
                 }
                 return answer;
         }
 
}
  • Main
public class BeverageTestDrive {
         public static void main(String[] args) {
                 TeaWithHook teaWithHook = new TeaWithHook();
                 CoffeeWithHook coffeeWithHook = new CoffeeWithHook();
                 
                 System.out.println("\n Making tea");
                 teaWithHook.prepareRecipe();
                 
                 System.out.println("\nMaking coffee");
                 coffeeWithHook.prepareRecipe();
         }
}

결과

Making tea

Boiling water

Steeping the tea

Pouring into cup

would you like lemon with your tea (y/n) ?

y

Adding Lemon

Making coffee

Boiling water

Dripping Coffee through filter

Pouring into cup

would you like milk &sugar with your coffee (y/n) ?

y

Adding Sugar and Milk

UML

profile
Frontend

0개의 댓글