Template method slouží k definování kostry obecného algoritmu, aniž bychom znali jeho konkrétní kroky. Tuto kostru posléze můžeme použít pro implementaci jednotlivých specifických algoritmů z ní vycházejících.
Jádrem vzoru je abstraktní třída specifikující kostru algoritmu (obecný postup), která využívá abstraktních metod tatktéž definovaných v této třídě. Děděním a specifikací těchto abstraktních metod dojde k doplnění šablony na plnohodnotný algoritmus. Výhodou tohoto postupu je neopakování kostry v každé specifikaci a snadná zaměnitelnost specifikací prostřednictvím abstraktního předka.
Příklad
Implementací tohoto vzoru je algoritmus pro vaření polévek. Polévky se dělají velmi podobným zůsobem - upravíme suroviny, přidáme je do hrnce s vodou a vaříme, dokud není hotovo. To je kostra algoritmu, specifické metody definují, co to znamená upravit suroviny, kdy je hotovo atp.
001.
/**
002.
* Template pro vareni polevky
003.
* @author Pavel Micka
004.
*/
005.
abstract
class
AbstractCookSoupAlgorithm{
006.
/**
007.
* Kostra algoritmu - template method
008.
* @return polevka
009.
*/
010.
public
String cookSoup(){
011.
String[] ingredients = getIngredients();
012.
prepareIngredients(ingredients);
013.
addWater();
014.
while
(!finished()){
015.
boil();
016.
}
017.
System.out.println(
"Polevka je uvarena"
);
018.
return
"Uvarena polevka"
;
019.
}
020.
/**
021.
* Suroviny do polevky
022.
* @return suroviny
023.
*/
024.
protected
abstract
String[] getIngredients();
025.
/**
026.
* Pripravi suroviny
027.
* @param ingredients suroviny
028.
*/
029.
protected
abstract
void
prepareIngredients(String[] ingredients);
030.
/**
031.
* Je polevka hotova
032.
* @return @true pokud je uvareno, @false pokud neni uvareno
033.
*/
034.
protected
abstract
boolean
finished();
035.
/**
036.
* Prida vodu do polevky
037.
*/
038.
protected
abstract
void
addWater();
039.
/**
040.
* Vari polevku
041.
*/
042.
protected
abstract
void
boil();
043.
}
044.
045.
class
CookInstantSoupAlgorithm
extends
AbstractCookSoupAlgorithm{
046.
047.
@Override
048.
protected
String[] getIngredients() {
049.
return
new
String[]{
"Sacek instantni gulasove polevky"
};
050.
}
051.
052.
@Override
053.
protected
void
prepareIngredients(String[] ingredients) {
054.
System.out.println(
"Oteviram sacek"
);
055.
}
056.
057.
@Override
058.
protected
boolean
finished() {
059.
//bud 0 nebo jedna
060.
Random r =
new
Random(System.currentTimeMillis());
061.
if
(r.nextInt(
2
) ==
0
)
return
true
;
//zelenina je mekka, uvareno
062.
return
false
;
063.
}
064.
065.
@Override
066.
protected
void
addWater() {
067.
System.out.println(
"Pridavam hrnek varici vody"
);
068.
}
069.
070.
@Override
071.
protected
void
boil() {
072.
//nic nedelame, protoze se hrnickova polevka nevari
073.
}
074.
075.
}
076.
077.
class
CookVegetableSoupAlgorithm
extends
AbstractCookSoupAlgorithm{
078.
079.
@Override
080.
protected
String[] getIngredients() {
081.
return
new
String[]{
"mrkev, celer, petrzel, 2x slepisi bujon, cibule, cesnek, brambory"
};
082.
}
083.
084.
@Override
085.
protected
void
prepareIngredients(String[] ingredients) {
086.
for
(String ingredient : ingredients){
087.
System.out.println(
"Krajim "
+ ingredient);
088.
}
089.
}
090.
091.
@Override
092.
protected
boolean
finished() {
093.
//bud 0 az 4
094.
Random r =
new
Random(System.currentTimeMillis());
095.
if
(r.nextInt(
5
) ==
0
)
return
true
;
096.
return
false
;
097.
}
098.
099.
@Override
100.
protected
void
addWater() {
101.
System.out.println(
"Pridavam 2 litry vody"
);
102.
}
103.
104.
@Override
105.
protected
void
boil() {
106.
System.out.println(
"Varim na strednim plamenu"
);
107.
}
108.
}
Literatura
- PECINOVSKÝ, Rudolf. Návrhové vzory. 1. vyd. [s.l.] : Computer press, 2007. 527 s. ISBN 978-80-2511582-4.