템플릿 메서드 패턴은 메서드 안에 단계별로 메서드를 정의한 후, 이 중 몇몇 메서드는 서브 클래스에서 구현할 수 있도록 하는 패턴이다.

메서드는 알고리즘의 골격을 정의하고, 실제 알고리즘은 서브 클래스가 구현하는 방식이다.

예를 들어보자면, 커피 클래스와 차(Tea) 클래스가 있다고 가정해보자.

커피 클래스

public class Coffee {
	void prepareRecipe() {
		boilWater();
		brewCoffeeGrinds();
	}
	
	public void boilWater() {
		// boil water
	}
	
	public void brewCoffeeGrinds() {
		// brew Coffee Grinds
	}
}

차 클래스

public class Tea {
	void prepareRecipe() {
		boilWater();
		brewTeaBag();
	}
	
	public void boilWater() {
		// boil water
	}
	
	public void brewTeaBag() {
		// brew tea bag	
	}
}

만약 두 클래스를 추상화한다면, 같은 행동을 하는 boilWater() 함수를 가지고 있는 수퍼 클래스를 정의한 뒤, 두 클래스가 해당 클래스를 상속하면 될 것이다.

하지만 prepareRecipe() 함수의 경우는 어떨까? 비슷한 일을 하는 메서드이지만, 내용(알고리즘)이 달라 수퍼 클래스에서 구현할 수 없을 것 같다.

이 때, prepareRecipe() 메서드를 골격으로 하는 템플릿 메서드 패턴을 적용시키면 해결이 가능해진다.

brewCoffeeGrinds()와 brewTeaBag() 메서드는 실제 역할은 다르지만, 대략적인 내용은 비슷하다. 따라서 brew() 추상 메서드로 추출하여 수퍼 클래스에 위치한다.

따라서 수퍼 클래스는 다음과 같아진다.

// 상속한 클래스가 brew() 메서드를 구현할 수 있도록 추상 클래스로 선언
public abstract class CaffeineBeverage {
	// 알고리즘의 골격으로 정의해서 각 클래스는 세부 알고리즘만 구현할 수 있도록 함.
	final void prepareRecipe() {
		boilWater();
		brew();
	}
	
	// 두 클래스가 서로 brew() 알고리즘을 구현할 수 있도록 추상 메서드로 선언
	abstract void brew();
	
	void boilWater() {
		// 두 클래스에서 완전히 같은 기능을 하는 메서드는 여기에서 구현
	}
}

그리고 위 수퍼 클래스를 구현하게 되는 커피, 차 클래스는 다음과 같다.

public class Coffee extends CaffeineBeverage {
	@Override
	public void brew() {
		// brew coffee grids
	}
}
public class Tea extends CaffeineBeverage {
	@Override
	public void brew() {
		// brew tea bag
	}
}