Template Method ํจํด์ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌ์กฐ๋ ๊ทธ๋๋ก ๋๋ฉด์, ํน์ ๋จ๊ณ๋ง ๋ค๋ฅด๊ฒ ๊ตฌํํ ์ ์๊ฒ ํด์ฃผ๋ ๋์์ธ ํจํด์ด์์. ์ด ํํ ๋ฆฌ์ผ์ ๋ฐ๋ผํ๋ฉด Template Method ํจํด์ ํต์ฌ ๊ฐ๋ ์ ์ดํดํ๊ณ , ์ค์ ํ๋ก์ ํธ์์ ํ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.
ํ์ต๋ชฉํ
Template Method ํจํด์ ๋์ ์๋ฆฌ๋ฅผ ์ดํดํ๋ค
๊ฐ๋จํ ์์ ๋ฅผ ๊ตฌํํด๋ณธ๋ค
Template Method ํจํด์ ๋ค์๊ณผ ๊ฐ์ด ์ถ์ ํด๋์ค์ ๊ตฌํ ํด๋์ค๋ก ์ด๋ฃจ์ด์ง๋ ์์์ ์ด์ฉํ๋ ํจํด์ด์์.

Abstract Class (์ถ์ ํด๋์ค)
ํ ํ๋ฆฟ ๋ฉ์๋๋ฅผ ์ ์ํ์ฌ ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฒด ๊ตฌ์กฐ๋ฅผ ์ ๊ณต (๋ฉ์๋ => ์๊ณ ๋ฆฌ์ฆ ์คํ ๋ผ๋)
๊ฐ ๋จ๊ณ๋ฅผ ๋ํ๋ด๋ ์ถ์ ๋ฉ์๋๋ค์ ์ ์ธ
๊ณตํต ๋ก์ง์ ๊ตฌํํ๋ ๊ตฌ์ฒด์ ์ธ ๋ฉ์๋๋ค๋ ํฌํจ ๊ฐ๋ฅ
Concrete Class (๊ตฌํ ํด๋์ค)
์ถ์ ํด๋์ค๋ฅผ ์์๋ฐ์ ์ถ์ ๋ฉ์๋๋ค์ ๊ตฌํ
์๊ณ ๋ฆฌ์ฆ์ ํน์ ๋จ๊ณ๋ค์ ์์ ๋ง์ ๋ฐฉ์์ผ๋ก ์ ์
์ ๊ตฌ์กฐ์ ํํฌ๋ผ ๋ถ๋ฆฌ๋ ๋ฉ์๋๋ฅผ ์ถ์ ํด๋์ค์ ์ ์ธํ์ฌ ์ฌ์ฉํ๊ธฐ๋ ํด์. ํํฌ๋ ๊ธฐ๋ณธ์ ์ธ ๋ด์ฉ๋ง ๊ตฌํ๋์ด ์๊ฑฐ๋, ์๋ฌด ์ฝ๋๋ ๋ค์ด์์ง ์์ ๋ฉ์๋์์. ๋ณดํต ์๋ธํด๋์ค์์ ์๊ณ ๋ฆฌ์ฆ์ ๋ผ์ด๋๋๋ฐ ๋ง์ด ์ฌ์ฉ๋์.

์ด์ ์ ๊ตฌ์กฐ์ ๋ฐ๋ผ ์ปคํผ์ ์ฐจ๋ฅผ ๊ตฌํํ๋๋ฐ Template Method๋ฅผ ์ฌ์ฉํด ๋ณด์์. ์ ์ ๊ตฌ์กฐ๋ก Coffee์ Tea๋ฅผ ๊ตฌํํ๋์ง ๋ฐฐ๊ฒฝ์ ์ค๋ช ํด ๋ณผ๊ฒ์. Coffee์ Tea๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์๋๋ฐ, ๋ฌผ์ ๋์ด๊ณ , ์์ฌ๋ฃ๋ฅผ ๋ฃ์ด ์ถ์ถํ๊ณ , ์ปต์ ๋ถ๋ ๊ณผ์ ์ด ๊ฑฐ์ ๋น์ทํด์. ๊ทธ๋์ ์ด ๊ณผ์ ์ ๊ณตํตํ ํด์ ์ถ์ํ(์บก์ํ)ํ ์ ์๋ค๊ณ ํ๋จํ ์ ์์ด์.
๊ณตํต๋ Beverage๋ผ๋ ์ถ์ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ ์ ๊ณผ์ ์ prepareBeverage๋ผ๋ ๋ฉ์๋์์ ์์๋๋ก ๋จ๊ณ๋ณ ํจ์๋ฅผ ์คํํ๋๋ก ๋ง๋๋๊ฑฐ์์.์ด๋ ๊ฒ ์๊ณ ๋ฆฌ์ฆ ๋ผ๋ ์ญํ ์ ํด์ฃผ๋ ๋ฉ์๋๋ฅผ ํ ํ๋ฆฟ ๋ฉ์๋๋ผ๊ณ ํด์. ์ฌ๊ธฐ์ ํ ํ๋ฆฟ ๋ฉ์๋๋ prepareBeverage()์์.
prepareBeverage() ๋ฉ์๋์์๋ boilWater(), brew(), pourInCup()์ ์์๋๋ก ์คํํ๋ ๋ผ๋๊ฐ ๋์. ์ฌ๊ธฐ์ boilWater์ ์จ๋์ pourInCup์ Coffee๋ Tea๊ฐ ๋๊ฐ๋ค๊ณ ์๊ฐํ๊ณ brew()ํ๋ ๊ณผ์ ๋ง coffee์ tea์์ ๋ค๋ฅด๊ฒ ๋ง๋ค๊ณ ์ถ์ ๊ฑฐ์์. ๊ทธ๋์ brew๋ abstract ํจ์๋ก ์ ์ธํ์ฌ ๊ฐ๊ฐ ๊ตฌํ ํด๋์ค์์ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๋๋ก ๋ง๋ ๊ฑฐ์์.
Abstract Class (์ถ์ ํด๋์ค)
// ์ถ์ ํด๋์ค - ์ปคํผ์ ์ฐจ๋ฅผ ๋ง๋๋ ๊ณผ์ ์ ํ
ํ๋ฆฟabstract class Beverage { // ํ
ํ๋ฆฟ ๋ฉ์๋ - ์ ์ฒด ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌ์กฐ๋ฅผ ์ ์ public final void prepareBeverage() { boilWater(); brew(); pourInCup(); if (customerWantsCondiments()) { // ํํฌ๋ฅผ ์ฌ์ฉํด ์๋์ด ์ฒจ๊ฐ๋ฌผ ์ํ๋ ์ฌ๋ถ์ ๋ฐ๋ผ ํจ์ ์คํ ๊ฒฐ์ . addCondiments(); } } // ๊ณตํต ๋ฉ์๋๋ค private void boilWater() { System.out.println("๋ฌผ์ ๋์
๋๋ค"); } private void pourInCup() { System.out.println("์ปต์ ๋ฐ๋ฆ
๋๋ค"); } // ํ์ ํด๋์ค์์ ๊ตฌํํด์ผ ํ๋ ์ถ์ ๋ฉ์๋๋ค protected abstract void brew(); protected abstract void addCondiments(); // ํ
(hook) ๋ฉ์๋ - ํ์ ํด๋์ค์์ ์ ํ์ ์ผ๋ก ์ค๋ฒ๋ผ์ด๋ ๊ฐ๋ฅ protected boolean customerWantsCondiments() { return true; }}Concrete Class (๊ตฌํ ํด๋์ค)
// ์ปคํผ ํด๋์คclass Coffee extends Beverage { @Override protected void brew() { System.out.println("ํํฐ๋ก ์ปคํผ๋ฅผ ์ฐ๋ ค๋
๋๋ค"); } @Override protected void addCondiments() { System.out.println("์คํ๊ณผ ์ฐ์ ๋ฅผ ์ถ๊ฐํฉ๋๋ค"); }}// ์ฐจ ํด๋์คclass Tea extends Beverage { @Override protected void brew() { System.out.println("์ฐป์์ ์ฐ๋ ค๋
๋๋ค"); } @Override protected void addCondiments() { System.out.println("๋ ๋ชฌ์ ์ถ๊ฐํฉ๋๋ค"); } @Override protected boolean customerWantsCondiments() { return false; // ์ฐจ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฒจ๊ฐ๋ฌผ์ ๋ฃ์ง ์์ }Template Method ํจํด์ Factory Method ํจํด๊ณผ ๋น์ทํด ๋ณด์ฌ์. ๋ํ Strategy ํจํด๊ณผ ์ญํ ์ด ๋น์ทํด ๋ณด์ด๊ธฐ๋ ํด์. ๊ทธ๋์ ํ๋ก ์ ๋ฆฌํด๋ดค์ด์.
ํจํด | ๋ถ๋ฅ | ๋ชฉ์ | ๋ฒ์/ ์ ์ฉ ๋จ์ | ํต์ฌ |
|---|---|---|---|---|
Template Method | ํ์ ํจํด | ์๊ณ ๋ฆฌ์ฆ์ ๊ณจ๊ฒฉ์ ์ ์ํ๊ณ , ์ผ๋ถ ๋จ๊ณ๋ฅผ ์๋ธํด๋์ค์์ ๊ตฌํํ๋๋ก ์์ | ํด๋์ค: ์์ ํด๋์ค์์ ์๊ณ ๋ฆฌ์ฆ ๊ตฌ์กฐ ์ ์, ํ์ ํด๋์ค์์ ๊ตฌํ | ์์ ํด๋์ค์์ templateMethod() ์ ์ โ ํ์ ํด๋์ค๊ฐ ์ธ๋ถ ๋จ๊ณ ๊ตฌํ |
Factory Method | ์์ฑ ํจํด | ๊ฐ์ฒด ์์ฑ์ ์๋ธํด๋์ค์์ ์บก์ํํ์ฌ ํด๋ผ์ด์ธํธ ์ฝ๋์ ๋ถ๋ฆฌ | ํด๋์ค: ์ด๋ค ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ง ์๋ธํด๋์ค๊ฐ ๊ฒฐ์ | ๊ฐ์ฒด ์์ฑ ์ฝ๋๋ฅผ ์๋ธํด๋์ค์ ์์, ํด๋ผ์ด์ธํธ๋ ๊ตฌ์ฒด ํด๋์ค ๋ชฐ๋ผ๋ ๋จ |
Strategy | ํ์ ํจํด | ์๊ณ ๋ฆฌ์ฆ์ ์บก์ํํ๊ณ ๋ฐํ์์ ๊ต์ฒด ๊ฐ๋ฅํ๋๋ก ํ์ฌ ํ๋์ ๋์ ์ผ๋ก ๊ฒฐ์ | ๊ฐ์ฒด: ๊ฐ์ฒด๊ฐ ์ฌ์ฉํ ์๊ณ ๋ฆฌ์ฆ(ํ๋)์ ์ ํ/๊ต์ฒด ๊ฐ๋ฅ | ์๊ณ ๋ฆฌ์ฆ์ ๋ณ๋ Strategy ๊ฐ์ฒด๋ก ์ ์ โ ์ปจํ ์คํธ ๊ฐ์ฒด๊ฐ ์คํ ์ ์ ํ |
๊ทธ๋ฌ๋ฉด ์ด์ ์ด๋ ๊ฒฝ์ฐ์ Template Method๋ฅผ ์ฌ์ฉํ๊ณ , ์ด๋ ๊ฒฝ์ฐ์ธ Strategy ํจํด์ด๋ ๋ค๋ฅธ ํจํด์ ์ฌ์ฉํ ์ง ์ ๋ฆฌํด ๋ณผ๊ฒ์.
ํ ํ๋ฆฟ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ข์ ๊ฒฝ์ฐ
์ฌ๋ฌ ํด๋์ค์์ ๋์ผํ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ง๋ง ์ผ๋ถ๋ง ๋ค๋ฅผ ๋
์๊ณ ๋ฆฌ์ฆ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ ํ๊ณ ์ถ์ ๋ (๋ฉ์๋ ์์)
ํ๋ ์์ํฌ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ง๋ค ๋ (์๋ฐ์ Configuration ์๊ฐํด๋ณด๋ฉด ์ธ๋ถ ์๊ณ ๋ฆฌ์ฆ๋ง ์ ์ํ๋ฉด ๋)
ํ ํ๋ฆฟ ๋ฉ์๋๋ฅผ ํผํ๋ ๊ฒ์ด ์ข์ ๊ฒฝ์ฐ
๋ฐํ์์ ์๊ณ ๋ฆฌ์ฆ ๋ณ๊ฒฝ์ด ํ์ํ ๋ => ์์์ ์ด์ฉํ๊ธฐ ๋๋ฌธ์ ๋ถ๊ฐ๋ฅ
ํด๋์ค ๊ณ์ธต์ด ์ด๋ฏธ ๋ณต์กํ ๋
์ด์ Template Method ํจํด์ ๋ํด์ ์์ จ๋์?
๋ฐฐ์ด ๋ด์ฉ
Template Method ํจํด์ ๊ธฐ๋ณธ ๊ตฌ์กฐ์ ๋์ ์๋ฆฌ
Hook ๋ฉ์๋๋ฅผ ํ์ฉํ ์ ํ์ ๋จ๊ณ ๊ตฌํ ๋ฐฉ๋ฒ
๋ค๋ฅธ ๋์์ธ ํจํด๊ณผ์ ์ฐจ์ด์
Template Method ์ ์ฉ์ด ์ฅ์ ์ด ๋๋ ๊ฒฝ์ฐ์ ๋์ ๊ฒฝ์ฐ
Template Method ํจํด์ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌ์กฐํํ์ฌ ๋ช ํํ ํ๊ณ , ์ธ๋ถ ๊ตฌํ์ ํตํด ๋ค๋ฅด๊ฒ ์๋ํ๊ฒ ๋ง๋๋ ํจํด์ด์์. ๊ทธ๋์ ์ด ํจํด์ด ์ฌ์ฉ๋๋ ๋ํ์ ์ธ ์ ์ค ํ๋๊ฐ Java์ Array๊ฐ sort๊ฐ ํ ํ๋ฆฟ ๋ฉ์๋๊ณ compareTo๊ฐ ์ธ๋ถ ๊ตฌํ์ด ๋๋ ๊ฒฝ์ฐ์์. ๊ทธ๋ฆฌ๊ณ Spring์ Configuration๋ ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ ํด์ ์ค์ ํ๋ ๊ฒ๋ ํ๋ ์์ํฌ๋ฅผ ๋ง๋๋๋ฐ ์ฌ์ฉ๋๋ ์์์์. ์ฌ๋ฌ๋ถ๋ ์ ์ ํ ์ฌ์ฉํด ๋ณด์๋ฉด ์ข์๊ฒ ๊ฐ์์.