The Template Method Pattern

2023. 10. 22. 01:05디자인패턴

728x90

Template Method Pattern

 

:메소드에서 알고리즘의 뼈대를 정의하고, 구현은 서브클래스에서 하도록 하는 방법.

 

상속을 통해 슈퍼클래스의 기능을 확장할 때 사용하는 대표적인 방법.

 

변하지 않는 기능은 슈퍼클래스에 만들어주고 

자주 변경되며 확장할 기능은 서브클래스에 만들어준다.

 

여러 작업들이 동일한 동작을 하지만, 일부 동작은 다르게 구현해야 할 때 사용되는 패턴.

 

 

예시) 

 

커피 만드는 클래스

public class Coffee {
    void prepareRecipe() {
        boilWater();
        brewCoffeeGrinds();
        pourInCup();
        addSugarAndMilk();
    }
    public void boilWater() {
    	System.out.println(“Boiling water”);
    }
    public void brewCoffeeGrinds() {
    	System.out.println(“Dripping Coffee through filter”);
    }
    public void pourInCup() {
    	System.out.println(“Pouring into cup”);
    }
    public void addSugarAndMilk() {
    	System.out.println(“Adding Sugar and Milk”);
    }
}

티 만드는 클래스

public class Tea {
    void prepareRecipe() {
        boilWater();
        steepTeaBag();
        pourInCup();
        addLemon();
    }
    public void boilWater() {
    	System.out.println(“Boiling water”);
    }
    public void steepTeaBag() {
    	System.out.println(“Steeping the tea”);
    }
    public void addLemon() {
    	System.out.println(“Adding Lemon”);
    }
    public void pourInCup() {
    	System.out.println(“Pouring into cup”);
    }
}

이 두 클래스는 아래 표시된 두 메소드만 다르다.

 

두 클래스의 슈퍼클래스를 추상 클래스로 만들어보자

 

public abstract class CaffeineBeverage { 
    final void prepareRecipe() { //서브클래스가 사용가능하도록 final 키워드 사용
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
    abstract void brew(); //서브클래스에서 변경 가능하도록 abstract로 정의
    abstract void addCondiments(); //서브클래스에서 변경 가능하도록 abstract로 정의
    void boilWater() {
    	System.out.println(“Boiling water”);
    }
    void pourInCup() {
    	System.out.println(“Pouring into cup”);
    }
}
public class Tea extends CaffeineBeverage {
    public void brew() {
    	System.out.println(“Steeping the tea”);
    }
    public void addCondiments() {
    	System.out.println(“Adding Lemon”);
    }
}

public class Coffee extends CaffeineBeverage {
    public void brew() {
    	System.out.println(“Dripping Coffee through filter”);
    }
    public void addCondiments() {
    	System.out.println(“Adding Sugar and Milk”);
    }
}

 

 

 

Hook

: 추상클래스에서 선언되는 메소드

기본적인 내용만 구현되어 있거나 아무 코드도 들어있지 않은 메소드

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() { 
    //이 메소드는 서브클래스에서 필요에 따라 override 할 수 있는 hook이다.
    	return true;
    }
}

서브클래스에서 구현하여 사용

public class CoffeeWithHook extends CaffeineBeverageWithHook {
public void brew() {
	System.out.println(“Dripping Coffee through filter”);
}
public void addCondiments() {
	System.out.println(“Adding Sugar and Milk”);
}
public boolean customerWantsCondiments() {
    String answer = getUserInput();
    if (answer.toLowerCase().startsWith(“y”)) {
    	return true;
    } 
    else {
    	return false;
    }
}
private String getUserInput() {
	...
}

 

The Hollywood Principle

: 상위레벨에서 하위레벨은 호출가능하지만 
하위레벨이 상위레벨을 호출하면 안됨

서브클래스들은 추상클래스를 호출하지 않는다.

추상클래스는 서브클래스를 호출한다.

-> 전체 시스템의 의존성이 줄어든다.

728x90

'디자인패턴' 카테고리의 다른 글

composite pattern  (0) 2023.10.30
The iterator pattern  (0) 2023.10.22
The Adapter and Facade Patterns  (0) 2023.10.21
The Command Pattern  (1) 2023.10.21
The Singleton Pattern  (1) 2023.10.21