8. Template Method Pattern

최정훈·2024년 11월 20일

1. 메서드의 추상화


홍차와 커피는 카페인 음료라는 공통점도 있지만, 조리과정이 매우 유사하다는 공통점도 있다. 둘 다 공통적으로 물을 끓이고, 찻잎 또는 원두를 넣고, 잔에 따른다. 마지막으로 우유, 설탕, 레몬과 같은 첨가물을 넣는다. 그렇다면, 공통된 과정을 추상화 할 수도 있지 않을까? 아마도 다음과 같이 할 수 있을 것이다.

public abstract class CaffaeineBeverage{
	public void prepareRecipe(){} // 재료를 준비함
	public void boilWater(){}     // 물을 끓임
	public void pourInCup(){}     // 잔에 따름
}

위와 같이 공통된 부분을 클래스로 추상화하여 홍차와 커피가 상속하도록 하면, 원하는대로 작동할 것이다.

하지만, 이것보다 더 추상화 할 수는 없을까? 지금의 문제점은 일단 쓰는 재료와 마지막에 첨가하는 재료가 다르다는 점이다. 그렇다면 이를 brew() , addCondiments() 메서드를 통해서 공통적으로 묶으면 더욱 추상화가 가능하다. 아래는 그 코드이다.

public abstract class CaffaeineBeverage{
	final void prepareRecipe(){
		boilWater();
		brew();
		pourInCup();
		addCondiments();
	}
	
	abstract void brew();           // 서브 클래스에서 처리
	abstract void addCondiments();  // 서브 클래스에서 처리
	
	void boilWater(){} // 이 클래스에서 처리
	void pourInCup(){} // 이 클래스에서 처리
}

위의 코드에서 `prepareRecipe()` 는 template method이다. 카페인 음료를 만드는 알고리즘의 template(틀) 역할을 하기 때문이다. 이를 구성하는 메서드들은 해당 클래스에서 처리되기도 하고, 서브 클래스에서 처리되기도 한다.

2. Template Method Pattern


알고리즘의 골격을 정의한다. Template Method를 사용하면 알고리즘의 일부 단계를 서브 클래스에서 구현할 수 있으며, 알고리즘의 구조는 그대로 유지하면서 알고리즘의 특정 단계를 서브 클래스에서 재정의할 수도 있다.

간단하게 말하면 일련의 단계로 알고리즘을 정의한 메서드이다. 여러 단계 가운데 하나 이상의 단계가 추상 메서드로 정의되며, 그 추상 메서드는 서브 클래스에서 구현된다.

또한, 아무것도 하지 않는 메서드를 포함할 수도 있는데 이러한 메서드를 hook이라고 한다. hook은 서브 클래스에서 오버라이드할 수도 있지만, 그렇지 않을 수도 있다. 알고리즘의 특정 단계가 선택적으로 실행되면 hook을 추가해도 된다. 주로 필수적이지 않은 부분을 서브 클래스에 구현하는데 사용되거나, 앞으로 일어날 일에 서브 클래스가 반응할 수 있도록 기회를 제공하는 용도로 사용된다.

3. Hollywood Principle


이를 사용하면 의존성 부패를 방지할 수 있다. 의존성이 복잡하게 꼬여있는 상황을 두고 의존성이 부패했다고 하는데, Hollywood Principle을 사용하면 저수준 구성요소를 사용할지 말지를 고수준 구성요소가 결정한다. 위에서 살펴보았던 커피와 홍차의 예시에서 본다면, CaffaeineBeverage 클래스에 의해서 호출되기 전까지, CoffeeTea의 추상클래스는 호출되지 않는다.

profile
게임개발자(희망)의 공부일지

0개의 댓글