Template Method


V této části si ukážeme Template Method. Tento návrhový vzor nám umožňuje definovat kostru algoritmu, který můžeme implementovat v podtřídách.

Proč Template Method použít

Algoritmy mohou být rozloženy na vyšší část (funkčnost) a nižší část (implementaci). To nám umožňuje algoritmus použít na více věcí najednou. U návrhové vzoru Strategy používá vyšší část algoritmu nějaké rozhraní. Konkrétní implementace implementuje nějaké rozhraní. Návrhový vzor Template Method funguje podobně, ale využívá dědičnosti. Třída implementující algoritmus definuje abstraktní metody, které algoritmus používá, a tyto metody mohou podtřídy přepsat a nadefinovat si tak vlastní části algoritmu.

Příklad - Implementace algoritmu v podtřídách

Následující ukázka ukazuje třídu Hra, která obsahuje metodu spust. Tato metoda používá metody, které jsou implementovány podtřídami. V ukázce je třída Sachy, která je podtřídou třídy Hra a implementuje metody, které metoda spust volá.

class Hra {
    constructor(pocetHracu) {
        this.pocetHracu = pocetHracu;
        this.aktualniHrac = 0;
    }

    // Template Metoda
    // - tuto metodu nepřepisujeme, jedná se o algoritmus, který
    // - volá metody, které jsou přepisovány v podtřídách
    spust() {
        // na začátku hry se zavolá metoda start
        this.start();
        // metoda vzitTah se bude volat tak dlouho, dokud někdo nevyhraje
        while (!this.maViteze) {
            this.vzitTah();
        }
        // po skončení hry se vypíše vítězný hráč
        console.log(`Hráč ${this.viteznyHrac} vyhrál.`);
    }

    // tyto metody přepisujeme v podtřídách
    start() {}
    get maViteze() {}
    vzitTah() {}
    get viteznyHrac() {}
}

// vytvoření hry Šachy
// - přepisují se metody třídy Hra
// - je to jen pro ukázku, nefunguje to jako šachy
class Sachy extends Hra {
    constructor() {
        super(2);
        this.maxPocetTahu = 10;
        this.tah = 1;
    }

    start() {
        console.log(`Začíná hra šachy s ${this.pocetHracu} hráči.`);
    }

    get maViteze() {
        return this.tah === this.maxPocetTahu;
    }

    vzitTah() {
        console.log(`Tah ${this.tah++} byl zahrán hráčem ${this.aktualniHrac}`);
        this.aktualniHrac = (this.aktualniHrac + 1) % this.pocetHracu;
    }

    get viteznyHrac() {
        // vítězný hráč bude v našem případě aktuální
        // hráč, což je samozřejmě nesmysl
        return this.aktualniHrac;
    }
}


const sachy = new Sachy();
// zavolání template metody
sachy.spust();