Assembled by GimunLee (2019-12-05)
- Template Method Pattern์ ๊ฐ๋ ์ ์ ์ ์๋ค.
- Template Method Pattern์ ์ฌ์ฉ ์ด์ ์ ๋ํด ์ค๋ช ํ ์ ์๋ค.
- Template Method Pattern์ ์ฌ์ฉํ ์ ์๋ค.
- ํ๋ฆฌ์ฐ๋ ์์น๊ณผ Template Method Pattern์ ๊ด๊ณ์ ๋ํด ์ค๋ช ํ ์ ์๋ค.
Template Method Pattern
์์๋ ๋ฉ์๋์์ ์๊ณ ๋ฆฌ์ฆ์ ๊ณจ๊ฒฉ์ ์ ์ํฉ๋๋ค. ์๊ณ ๋ฆฌ์ฆ์ ์ฌ๋ฌ ๋จ๊ณ ์ค ์ผ๋ถ๋ ์๋ธํด๋์ค์์ ๊ตฌํํ ์ ์์ต๋๋ค. ํ
ํ๋ฆฟ ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ฉด ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌ์กฐ๋ ๊ทธ๋๋ก ์ ์งํ๋ฉด์ ์๋ธํด๋์ค์์ ํน์ ๋จ๊ณ๋ฅผ ์ฌ์ ์ํ ์ ์์ต๋๋ค.
์ด๋ฒ ์ฅ์์๋ ์ฃผ์ด์ง ์ํฉ์ ํตํด Template Method Pattern์ ์ฌ์ฉ ์ด์ ๊ณผ ๊ตฌํ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์คํ๋ฒ์ฆ ์ปคํผ ๋ง๋๋ ๋ฒ
- ๋ฌผ์ ๋์ธ๋ค.
- ๋๋ ๋ฌผ์ ์ปคํผ๋ฅผ ์ฐ๋ ค๋ธ๋ค.
- ์ปคํผ๋ฅผ ์ปต์ ๋ฐ๋ฅธ๋ค.
- ์คํ๊ณผ ์ฐ์ ๋ฅผ ์ถ๊ฐํ๋ค.
์คํ๋ฒ์ฆ ํ์ฐจ ๋ง๋๋ ๋ฒ
- ๋ฌผ์ ๋์ธ๋ค.
- ๋๋ ๋ฌผ์ ์ฐจ๋ฅผ ์ฐ๋ ค๋ธ๋ค.
- ์ฐจ๋ฅผ ์ปต์ ๋ฐ๋ฅธ๋ค.
- ๋ ๋ชฌ์ ์ถ๊ฐํ๋ค.
์์ ๊ฐ์ ๋ฉ๋ด์ผ์ ์ฝ๋ฉ์ผ๋ก ๊ตฌํํ๋ค๋ฉด ์ฌ๋ฌ๋ถ์ ์ด๋ป๊ฒ ๊ตฌํํ์ค๊ฑด๊ฐ์?
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("์คํ๊ณผ ์ฐ์ ๋ฅผ ์ถ๊ฐํ๋ ์ค");
}
}
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 ์ฌ์ด์ ๊ณตํต์ ์ด ๋ ์๋์ง ์๊ฐํด ๋ด ์๋ค.
์ปคํผ์ ํ์ฐจ ์ฌ์ด์ ๋๋ค๋ฅธ ๊ณตํต์ ์ ๋ง๋๋ ๋ฒ์ ์๊ณ ๋ฆฌ์ฆ ์ด ๋๊ฐ๋ค๋ ๊ฒ ์ ๋๋ค. ๋ค์ ํ๋ฒ ์คํ๋ฒ์ฆ์ ๋ฉ๋ด์ผ์ ์ดํด๋ณด๋ฉด,
- ๋ฌผ์ ๋์ธ๋ค.
- ๋จ๊ฑฐ์ด ๋ฌผ์ ์ด์ฉํ์ฌ
์ปคํผ ๋๋ ํ์ฐจ
๋ฅผ ์ฐ๋ ค๋ธ๋ค. - ๋ง๋ค์ด์ง ์๋ฃ๋ฅผ ์ปต์ ๋ฐ๋ฅธ๋ค.
- ๊ฐ ์๋ฃ์ ๋ง๋ ์ฒจ๊ฐ๋ฌผ์ ์ถ๊ฐํ๋ค.
์ด๋ ๊ฒ ๋ณด๋, ์ด๋ฏธ ์ถ์ํํ 1๋ฒ, 3๋ฒ ์ด์ธ์๋ ๋๋จธ์ง 2๋ฒ, 4๋ฒ ๋ํ ์ถ์ํ๊ฐ ๊ฐ๋ฅํ ๊ฒ ๊ฐ์ต๋๋ค. ๋จผ์ , ์ปคํผ์ ํ์ฐจ์์ ์ฌ์ฉํด๋ ์ด์ํ์ง ์๋๋ก ์ํผํด๋์ค์ ๋ฉ์๋ ์ด๋ฆ์ ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค.
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("์ปต์ ๋ฐ๋ฅด๋ ์ค");
}
}
public class Tea extends CaffeineBeverage {
public void brew() {
System.out.println("์ฐจ๋ฅผ ์ฐ๋ ค๋ด๋ ์ค");
}
public void addCondiments() {
System.out.println("๋ ๋ชฌ์ ์ถ๊ฐํ๋ ์ค");
}
}
public class Coffee extends CaffeineBeverage {
public void brew() {
System.out.println("ํํฐ๋ก ์ปคํผ๋ฅผ ์ฐ๋ ค๋ด๋ ์ค");
}
public void addCondiments() {
System.out.println("์คํ๊ณผ ์ปคํผ๋ฅผ ์ถ๊ฐํ๋ ์ค");
}
}
์ด์ฒ๋ผ Template Method Pattern
์์๋ ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ ๋จ๊ณ๋ค์ ์ ์ํ๋ฉฐ, ๊ทธ ์ค ํ ๊ฐ ์ด์์ ๋จ๊ณ๊ฐ ์๋ธํด๋์ค์ ์ํด ์ ๊ณต๋ ์ ์์ต๋๋ค.
- CoffeineBeverage ํด๋์ค์์ ์์ ์ ์ฒ๋ฆฌํฉ๋๋ค. ์๊ณ ๋ฆฌ์ฆ์ ํผ์ ๋ ์ ํ๊ณ ์์ต๋๋ค.
- CoffeineBeverage ๋๋ถ์ ์๋ธํด๋์ค์์ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ์๊ณ ๋ฆฌ์ฆ์ ํ ๊ตฐ๋ฐ์ ๋ชจ์ฌ ์๊ธฐ ๋๋ฌธ์ ๊ทธ ๋ถ๋ถ๋ง ๊ณ ์น๋ฉด ๋ฉ๋๋ค.
- Template Method Pattern์ ์ฌ์ฉํ๋ ๋ฒ์ ์์๋ ๋ค๋ฅธ ์นดํ์ธ ์๋ฃ๋ ์ฝ๊ฒ ์ถ๊ฐํ ์ ์๋ ํ๋ ์์ํฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์นดํ์ธ ์๋ฃ๋ฅผ ์ถ๊ฐํ ๋ ๋ช ๊ฐ์ง ๋ฉ์๋๋ง ์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค.
- CaffeineBeverage ํด๋์ค์ ์๊ณ ๋ฆฌ์ฆ์ ๋ํ ์ง์์ด ์ง์ค๋์ด ์์ผ๋ฉด ์ผ๋ถ ๊ตฌํ๋ง ์๋ธํด๋์ค์ ์์กดํฉ๋๋ค.
ํํฌ(hook)๋ ์ถ์ ํด๋์ค์์ ์ ์ธ๋๋ ๋ฉ์๋๊ธด ํ์ง๋ง ๊ธฐ๋ณธ์ ์ธ ๋ด์ฉ๋ง ๊ตฌํ๋์ด ์๊ฑฐ๋ ์๋ฌด ์ฝ๋๋ ๋ค์ด์์ง ์์ ๋ฉ์๋์ ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์๋ธํด๋์ค ์ ์ฅ์์๋ ๋ค์ํ ์์น์์ ์๊ณ ๋ฆฌ์ฆ์ ๋ผ์ด๋ค ์ ์์ต๋๋ค.
ํํฌ๋ ๋ค์ํ ์ฉ๋๋ก ์ฌ์ฉํ ์ ์๋๋ฐ ์ฐ์ ํ๊ฐ์ง ์ฌ์ฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
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)
๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์์กด์ฑ ๋ถํจ๋ ๊ตฌ์ฑ์์ ๊ฐ์ ์์กด์ฑ์ด ๋ณต์กํ๊ฒ ๊ผฌ์ฌ์๋ ๊ฒ์ ์ํ๋๋ฐ, ์ด๋ ๊ฒ ์์กด์ฑ์ด ๋ถํจํ๋ฉด ์์คํ
์ด ์ด๋ค ์์ผ๋ก ๋์์ธ๋ ๊ฒ์ธ์ง ๊ฑฐ์ ์๋ฌด๋ ์์๋ณผ ์ ์๊ฒ ๋ฉ๋๋ค.
ํ๋ฆฌ์ฐ๋ ์์น์ ์ฌ์ฉํ๋ฉด, ์ ์์ค ๊ตฌ์ฑ์์์์ ์์คํ ์ ์ ์์ ํ ์๋ ์์ง๋ง, ์ธ์ ์ด๋ค ์์ผ๋ก ๊ทธ ๊ตฌ์ฑ์์๋ค์ ์ฌ์ฉํ ์ง๋ ๊ณ ์์ค ๊ตฌ์ฑ์์์์ ๊ฒฐ์ ํ๊ฒ ๋ฉ๋๋ค. ์ฆ, ๊ณ ์์ค ๊ตฌ์ฑ์์์์ ์ ์์ค ๊ตฌ์ฑ์์์๊ฒ "๋จผ์ ์ฐ๋ฝํ์ง๋ง์ธ์. ์ ๊ฐ ๋จผ์ ์ฐ๋ฝ๋๋ฆฌ๊ฒ ์ต๋๋ค." ๋ผ๊ณ ์๊ธฐ๋ฅผ ํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
์์ ์์ ์์ ์ค๋ช ํ์๋ฉด, CaffeineBeverage๋ ๊ณ ์์ค ๊ตฌ์ฑ์์์ ๋๋ค. ์๋ฃ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ํด๋นํ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ฅ์ ํ๊ณ ์๊ณ , ๋ฉ์๋ ๊ตฌํ์ด ํ์ํ ์ํฉ์์๋ง ์๋ธํด๋์ค๋ฅผ ๋ถ๋ฌ๋ ๋๋ค.
์๋ธํด๋์ค๋ ์์ง๊ตฌ๋ ํ ๋ฉ์๋ ๊ตฌํ์ ์ ๊ณตํ๊ธฐ ์ํ ์ฉ๋๋ก๋ง ์ฌ์ฉ๋ฉ๋๋ค.
CaffaeineBeverage ํด๋์ค์ ํด๋ผ์ด์ธํธ์์๋ Tea๋ Coffee ๊ฐ์ ๊ตฌ์ ํด๋์ค๊ฐ ์๋ CaffeineBeverage์ ์ถ์ํ๋์ด ์๋ ๋ถ๋ถ์ ์์กดํ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ ๊ฒ ํจ์ผ๋ก์จ ์ ์ฒด ์์คํ ์ ์์กด์ฑ์ด ์ค์ด๋ค ์ ์์ต๋๋ค.
์ด ๋ฐ์๋ ํ๋ฆฌ์ฐ๋ ์์น์ ์ฌ์ฉํ๋ ๋์์ธ ํจํด์๋ Factory Method Pattern , Observer Pattern ๋ฑ์ด ์์ต๋๋ค.
Template Method Pattern์ ํ๋ ์์ํฌ๋ฅผ ๋ง๋๋ ๋ฐ ์์ฃผ ํ๋ฅญํ ๋์์ธ ๋๊ตฌ๋ผ๊ณ ํฉ๋๋ค. ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ์์ ์ด ์ฒ๋ฆฌ๋๋ ๋ฐฉ์์ ์ ์ดํ ์ ์์ผ๋ฉด์๋, ํ๋ ์์ฐํฌ์์ ์ฒ๋ฆฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ ๋จ๊ณ๋ ๊ทธ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋ ๋ง์๋๋ก ์ง์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
Template Method Pattern์ Strategy Pattern์ ์๋นํ ์ ์ฌํด๋ณด์ด๋๋ฐ, ๋ถ๋ช ํ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์ด ๋ถ๋ถ์ ๋ํด์๋ ์ถํ ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค.
- HeadFirstDesignPattern