# Template Method Pattern
Assembled by GimunLee
# Goal
- Template Method Patternμ κ°λ μ μ μ μλ€.
- Template Method Patternμ μ¬μ© μ΄μ μ λν΄ μ€λͺ ν μ μλ€.
- Template Method Patternμ μ¬μ©ν μ μλ€.
- ν리μ°λ μμΉκ³Ό Template Method Patternμ κ΄κ³μ λν΄ μ€λͺ ν μ μλ€.
# What is Template Method Pattern?
Template Method Pattern
μμλ λ©μλμμ μκ³ λ¦¬μ¦μ 골격μ μ μν©λλ€. μκ³ λ¦¬μ¦μ μ¬λ¬ λ¨κ³ μ€ μΌλΆλ μλΈν΄λμ€μμ ꡬνν μ μμ΅λλ€. ν
νλ¦Ώ λ©μλλ₯Ό μ΄μ©νλ©΄ μκ³ λ¦¬μ¦μ ꡬ쑰λ κ·Έλλ‘ μ μ§νλ©΄μ μλΈν΄λμ€μμ νΉμ λ¨κ³λ₯Ό μ¬μ μν μ μμ΅λλ€.
μ΄λ² μ₯μμλ μ£Όμ΄μ§ μν©μ ν΅ν΄ Template Method Patternμ μ¬μ© μ΄μ κ³Ό ꡬν λ°©λ²μ λν΄ μμ보λλ‘ νκ² μ΅λλ€.
# μ€νλ²μ¦ μ»€νΌ λ°λ¦¬μ€ν νλ ¨μ© λ©λ΄μΌ
μ€νλ²μ¦ μ»€νΌ λ§λλ λ²
- λ¬Όμ λμΈλ€.
- λλ λ¬Όμ 컀νΌλ₯Ό μ°λ €λΈλ€.
- 컀νΌλ₯Ό μ»΅μ λ°λ₯Έλ€.
- μ€νκ³Ό μ°μ λ₯Ό μΆκ°νλ€.
μ€νλ²μ¦ νμ°¨ λ§λλ λ²
- λ¬Όμ λμΈλ€.
- λλ λ¬Όμ μ°¨λ₯Ό μ°λ €λΈλ€.
- μ°¨λ₯Ό μ»΅μ λ°λ₯Έλ€.
- λ λͺ¬μ μΆκ°νλ€.
μμ κ°μ λ©λ΄μΌμ μ½λ©μΌλ‘ ꡬννλ€λ©΄ μ¬λ¬λΆμ μ΄λ»κ² ꡬννμ€κ±΄κ°μ?
# μΌλ°μ μΈ μ»€νΌ λ° νμ°¨ ν΄λμ€ λ§λ€κΈ° (JAVA)
# Coffee Class
public class Coffee {
void prepareRecipe(){
boilWater(); // λ¬Όμ λμΈλ€.
brewCoffeeGrinds(); // λλ λ¬Όμ 컀νΌλ₯Ό μ°λ €λΈλ€.
pourInCup(); // 컀νΌλ₯Ό μ»΅μ λ°λ₯Έλ€.
addSugarAndMilk(); // μ€νκ³Ό μ°μ λ₯Ό μΆκ°νλ€.
}
public void boilWater(){
System.out.println("λ¬Ό λμ΄λ μ€");
}
public void brewCoffeeGrinds(){
System.out.println("νν°λ₯Ό ν΅ν΄μ 컀νΌλ₯Ό μ°λ €λ΄λ μ€");
}
public void pourInCup(){
System.out.println("μ»΅μ λ°λ₯΄λ μ€");
}
public void addSugarAndMilk(){
System.out.println("μ€νκ³Ό μ°μ λ₯Ό μΆκ°νλ μ€");
}
}
# Tea Class
public class Tea {
void prepareRecipe(){
boilWater(); // λ¬Όμ λμΈλ€.
steepTeaBag(); // λλ λ¬Όμ μ°¨λ₯Ό μ°λ €λΈλ€.
pourInCup(); // μ°¨λ₯Ό μ»΅μ λ°λ₯Έλ€.
addLemon(); // λ λͺ¬μ μΆκ°νλ€.
}
public void boilWater(){
System.out.println("λ¬Ό λμ΄λ μ€");
}
public void steepTeaBag(){
System.out.println("μ°¨λ₯Ό μ°λ €λ΄λ μ€");
}
public void pourInCup(){
System.out.println("μ»΅μ λ°λ₯΄λ μ€");
}
public void addLemon(){
System.out.println("λ λͺ¬μ μΆκ°νλ μ€");
}
}
μ½λκ° μ€λ³΅λμ΄ μμΌλ©΄ λμμΈμ κ³ μ³μΌ νμ§ μμκΉ μκ°ν΄ 보λ κ²μ΄ μ’μ΅λλ€. Coffeeνκ³ Tea ν΄λμ€κ° κ±°μ λκ°μΌλκΉ κ³΅ν΅μ μΈ λΆλΆμ μΆμνμμΌμ λ² μ΄μ€ ν΄λμ€λ₯Ό λ§λλ κ²μ΄ μ’μ§ μμκΉμ?
# μΌλ°μ μΈ μ»€νΌ λ° νμ°¨ μΆμν
μ¬λ¬λΆλ μμ κ°μ΄ μκ°νμ ¨λμ? μ΄ λ°μ Coffeeμ Tea μ¬μ΄μ 곡ν΅μ μ΄ λ μλμ§ μκ°ν΄ λ΄ μλ€.
# Template Method Pattern μ¬μ©νκΈ°
컀νΌμ νμ°¨ μ¬μ΄μ λλ€λ₯Έ 곡ν΅μ μ λ§λλ λ²μ μκ³ λ¦¬μ¦ μ΄ λκ°λ€λ κ² μ λλ€. λ€μ νλ² μ€νλ²μ¦μ λ©λ΄μΌμ μ΄ν΄λ³΄λ©΄,
- λ¬Όμ λμΈλ€.
- λ¨κ±°μ΄ λ¬Όμ μ΄μ©νμ¬
μ»€νΌ λλ νμ°¨
λ₯Ό μ°λ €λΈλ€. - λ§λ€μ΄μ§ μλ£λ₯Ό μ»΅μ λ°λ₯Έλ€.
- κ° μλ£μ λ§λ 첨κ°λ¬Όμ μΆκ°νλ€.
μ΄λ κ² λ³΄λ, μ΄λ―Έ μΆμνν 1λ², 3λ² μ΄μΈμλ λλ¨Έμ§ 2λ², 4λ² λν μΆμνκ° κ°λ₯ν κ² κ°μ΅λλ€. λ¨Όμ , 컀νΌμ νμ°¨μμ μ¬μ©ν΄λ μ΄μνμ§ μλλ‘ μνΌν΄λμ€μ λ©μλ μ΄λ¦μ λ°κΏλ³΄κ² μ΅λλ€.
# CaffeineBeverage Class
public abstract class CaffeineBeverage {
final void prepareRecipe() { // μλΈν΄λμ€μμ μ΄ λ©μλλ₯Ό μ€λ²λΌμ΄λν΄μ μ무λ κ²λ
// μλ£λ₯Ό λ§λ€μ§ λͺ»νλλ‘ finalλ‘ μ μΈν΄μ€λλ€.
boilWater();
brew();
pourInCup();
addCondiments();
}
void boilWater() {
System.out.println("λ¬Όμ λμ΄λ μ€");
}
abstract void brew(); // Coffeeμ Teaμμ μ΄ λ©μλλ₯Ό μλ‘ λ€λ₯Έ λ°©μμΌλ‘
abstract void addCondiments(); // μ²λ¦¬νκΈ° λλ¬Έμ μΆμ λ©μλλ‘ μ μΈν΄μ€λλ€.
void pourInCup() {
System.out.println("μ»΅μ λ°λ₯΄λ μ€");
}
}
# Tea Class
public class Tea extends CaffeineBeverage {
public void brew() {
System.out.println("μ°¨λ₯Ό μ°λ €λ΄λ μ€");
}
public void addCondiments() {
System.out.println("λ λͺ¬μ μΆκ°νλ μ€");
}
}
# Coffee Class
public class Coffee extends CaffeineBeverage {
public void brew() {
System.out.println("νν°λ‘ 컀νΌλ₯Ό μ°λ €λ΄λ μ€");
}
public void addCondiments() {
System.out.println("μ€νκ³Ό 컀νΌλ₯Ό μΆκ°νλ μ€");
}
}
μ΄μ²λΌ Template Method Pattern
μμλ μκ³ λ¦¬μ¦μ κ° λ¨κ³λ€μ μ μνλ©°, κ·Έ μ€ ν κ° μ΄μμ λ¨κ³κ° μλΈν΄λμ€μ μν΄ μ 곡λ μ μμ΅λλ€.
# Template Method Patternμ μ¬μ© μ΄μ
- CoffeineBeverage ν΄λμ€μμ μμ μ μ²λ¦¬ν©λλ€. μκ³ λ¦¬μ¦μ νΌμ λ μ νκ³ μμ΅λλ€.
- CoffeineBeverage λλΆμ μλΈν΄λμ€μμ μ½λλ₯Ό μ¬μ¬μ©ν μ μμ΅λλ€.
- μκ³ λ¦¬μ¦μ ν κ΅°λ°μ λͺ¨μ¬ μκΈ° λλ¬Έμ κ·Έ λΆλΆλ§ κ³ μΉλ©΄ λ©λλ€.
- Template Method Patternμ μ¬μ©νλ λ²μ μμλ λ€λ₯Έ μΉ΄νμΈ μλ£λ μ½κ² μΆκ°ν μ μλ νλ μμν¬λ₯Ό μ 곡ν©λλ€. μΉ΄νμΈ μλ£λ₯Ό μΆκ°ν λ λͺ κ°μ§ λ©μλλ§ μΆκ°νλ©΄ λ©λλ€.
- CaffeineBeverage ν΄λμ€μ μκ³ λ¦¬μ¦μ λν μ§μμ΄ μ§μ€λμ΄ μμΌλ©΄ μΌλΆ ꡬνλ§ μλΈν΄λμ€μ μμ‘΄ν©λλ€.
# Template Method Patternκ³Ό Hook
νν¬(hook)λ μΆμ ν΄λμ€μμ μ μΈλλ λ©μλκΈ΄ νμ§λ§ κΈ°λ³Έμ μΈ λ΄μ©λ§ ꡬνλμ΄ μκ±°λ μ무 μ½λλ λ€μ΄μμ§ μμ λ©μλμ λλ€. μ΄λ κ² νλ©΄ μλΈν΄λμ€ μ μ₯μμλ λ€μν μμΉμμ μκ³ λ¦¬μ¦μ λΌμ΄λ€ μ μμ΅λλ€.
νν¬λ λ€μν μ©λλ‘ μ¬μ©ν μ μλλ° μ°μ νκ°μ§ μ¬μ©λ²μ μ΄ν΄λ³΄κ² μ΅λλ€.
# CaffeineBeverage Class
public abstract class CaffeineBeverageWithHook {
void prepareRecipe() {
boilWater();
brew();
pourInCup();
if(customerWantsCondiments()){
addCondiments();
}
}
void boilWater() {
System.out.println("λ¬Όμ λμ΄λ μ€");
}
abstract void brew();
abstract void addCondiments();
void pourInCup() {
System.out.println("μ»΅μ λ°λ₯΄λ μ€");
}
boolean customerWantsCondiments() { // μ΄ λ©μλλ μλΈν΄λμ€μμ νμμ λ°λΌ
return true; // μ€λ²λΌμ΄λ ν μ μλ λ©μλμ΄λ―λ‘ νν¬μ
λλ€.
}
}
μ΄ νν¬λ₯Ό μ¬μ©νλ €λ©΄, Coffeeλ Teaμ κ°μ μλΈν΄λμ€μμ νμμ λ°λΌ customerWantsConidments()
λ₯Ό μ€λ²λΌμ΄λν΄μ μλ£μ 첨κ°λ¬Όμ μΆκ°ν μ§ μ¬λΆλ₯Ό κ²°μ ν μ μμ΅λλ€.
# ν리μ°λ μμΉ
ν리μ°λ μμΉμ λμμΈ μμΉμΌλ‘ λ¨Όμ μ°λ½νμ§ λ§μΈμ. μ ν¬κ° μ°λ½λλ¦¬κ² μ΅λλ€.
μ
λλ€.
ν리μ°λ μμΉμ νμ©νλ©΄ μμ‘΄μ± λΆν¨(dependency rot)
λ₯Ό λ°©μ§ν μ μμ΅λλ€. μμ‘΄μ± λΆν¨λ ꡬμ±μμ κ°μ μμ‘΄μ±μ΄ 볡μ‘νκ² κΌ¬μ¬μλ κ²μ μνλλ°, μ΄λ κ² μμ‘΄μ±μ΄ λΆν¨νλ©΄ μμ€ν
μ΄ μ΄λ€ μμΌλ‘ λμμΈλ κ²μΈμ§ κ±°μ μ무λ μμλ³Ό μ μκ² λ©λλ€.
ν리μ°λ μμΉμ μ¬μ©νλ©΄, μ μμ€ κ΅¬μ±μμμμ μμ€ν μ μ μμ ν μλ μμ§λ§, μΈμ μ΄λ€ μμΌλ‘ κ·Έ ꡬμ±μμλ€μ μ¬μ©ν μ§λ κ³ μμ€ κ΅¬μ±μμμμ κ²°μ νκ² λ©λλ€. μ¦, κ³ μμ€ κ΅¬μ±μμμμ μ μμ€ κ΅¬μ±μμμκ² "λ¨Όμ μ°λ½νμ§λ§μΈμ. μ κ° λ¨Όμ μ°λ½λλ¦¬κ² μ΅λλ€." λΌκ³ μκΈ°λ₯Ό νλ κ²κ³Ό κ°μ΅λλ€.
# ν리μ°λ μμΉκ³Ό Template Method Pattern
μμ μμ μμ μ€λͺ νμλ©΄, CaffeineBeverageλ κ³ μμ€ κ΅¬μ±μμμ λλ€. μλ£λ₯Ό λ§λλ λ°©λ²μ ν΄λΉνλ μκ³ λ¦¬μ¦μ μ₯μ νκ³ μκ³ , λ©μλ ꡬνμ΄ νμν μν©μμλ§ μλΈν΄λμ€λ₯Ό λΆλ¬λ λλ€.
μλΈν΄λμ€λ μμ§κ΅¬λ ν λ©μλ ꡬνμ μ 곡νκΈ° μν μ©λλ‘λ§ μ¬μ©λ©λλ€.
CaffaeineBeverage ν΄λμ€μ ν΄λΌμ΄μΈνΈμμλ Teaλ Coffee κ°μ ꡬμ ν΄λμ€κ° μλ CaffeineBeverageμ μΆμνλμ΄ μλ λΆλΆμ μμ‘΄νκ² λ©λλ€. κ·Έλ κ² ν¨μΌλ‘μ¨ μ 체 μμ€ν μ μμ‘΄μ±μ΄ μ€μ΄λ€ μ μμ΅λλ€.
μ΄ λ°μλ ν리μ°λ μμΉμ μ¬μ©νλ λμμΈ ν¨ν΄μλ Factory Method Pattern , Observer Pattern λ±μ΄ μμ΅λλ€.
# Conclusion
Template Method Patternμ νλ μμν¬λ₯Ό λ§λλ λ° μμ£Ό νλ₯ν λμμΈ λꡬλΌκ³ ν©λλ€. νλ μμν¬λ₯Ό μ¬μ©ν¨μΌλ‘μ¨ μμ μ΄ μ²λ¦¬λλ λ°©μμ μ μ΄ν μ μμΌλ©΄μλ, νλ μμ°ν¬μμ μ²λ¦¬νλ μκ³ λ¦¬μ¦μ κ° λ¨κ³λ κ·Έ νλ μμν¬λ₯Ό μ¬μ©νλ μ¬λ λ§μλλ‘ μ§μ ν μ μκΈ° λλ¬Έμ λλ€.
Template Method Patternμ Strategy Patternμ μλΉν μ μ¬ν΄λ³΄μ΄λλ°, λΆλͺ ν μ°¨μ΄κ° μμ΅λλ€. μ΄ λΆλΆμ λν΄μλ μΆν μ 리ν΄λ³΄κ² μ΅λλ€.
# References
- Head First Design Patterns
β Strategy Pattern Memo β