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.
/** * Template pro vareni polevky * @author Pavel Micka */ abstract class AbstractCookSoupAlgorithm{ /** * Kostra algoritmu - template method * @return polevka */ public String cookSoup(){ String[] ingredients = getIngredients(); prepareIngredients(ingredients); addWater(); while(!finished()){ boil(); } System.out.println("Polevka je uvarena"); return "Uvarena polevka"; } /** * Suroviny do polevky * @return suroviny */ protected abstract String[] getIngredients(); /** * Pripravi suroviny * @param ingredients suroviny */ protected abstract void prepareIngredients(String[] ingredients); /** * Je polevka hotova * @return @true pokud je uvareno, @false pokud neni uvareno */ protected abstract boolean finished(); /** * Prida vodu do polevky */ protected abstract void addWater(); /** * Vari polevku */ protected abstract void boil(); } class CookInstantSoupAlgorithm extends AbstractCookSoupAlgorithm{ @Override protected String[] getIngredients() { return new String[]{"Sacek instantni gulasove polevky"}; } @Override protected void prepareIngredients(String[] ingredients) { System.out.println("Oteviram sacek"); } @Override protected boolean finished() { //bud 0 nebo jedna Random r = new Random(System.currentTimeMillis()); if(r.nextInt(2) == 0) return true; //zelenina je mekka, uvareno return false; } @Override protected void addWater() { System.out.println("Pridavam hrnek varici vody"); } @Override protected void boil() { //nic nedelame, protoze se hrnickova polevka nevari } } class CookVegetableSoupAlgorithm extends AbstractCookSoupAlgorithm{ @Override protected String[] getIngredients() { return new String[]{"mrkev, celer, petrzel, 2x slepisi bujon, cibule, cesnek, brambory"}; } @Override protected void prepareIngredients(String[] ingredients) { for(String ingredient : ingredients){ System.out.println("Krajim " + ingredient); } } @Override protected boolean finished() { //bud 0 az 4 Random r = new Random(System.currentTimeMillis()); if(r.nextInt(5) == 0) return true; return false; } @Override protected void addWater() { System.out.println("Pridavam 2 litry vody"); } @Override protected void boil() { System.out.println("Varim na strednim plamenu"); } }
Literatura
- PECINOVSKÝ, Rudolf. Návrhové vzory. 1. vyd. [s.l.] : Computer press, 2007. 527 s. ISBN 978-80-2511582-4.