Wzorzec Metoda Szablonowa

Metoda Szablonowa jest wzorcem, za pomocą którego możemy zdefiniować szablon algorytmu. Poszczególne kroki algorytmu w szablonie są definiowane jako oddzielne metody. Metody mogą być obsługiwane zarówno przez klasę, w której zawiera się metoda szablonowa, jak i przez klasy podrzędne. Metody, które mają być implementowane przez klasy podrzędne, są metodami abstrakcyjnymi. Klasy podrzędne mają możliwość redefiniowania poszczególnych kroków algorytmu, jednak nie mogą zmieniać jego struktury. Zaletą Metody Szablonowej jest zlokalizowanie algorytmu w jednym miejscu, co wpływa na łatwiejsze wprowadzanie potencjalnych zmian w kodzie.

Rys 1. Diagram UML – wzorzec Metoda Szablonowa.

W KlasieAbstrakcyjnej możemy stosować również tzw. „haczyki” – metody rzeczywiste, które nic nie robią, posiadają pustą lub domyślną implementację. W zależności od potrzeb, klasy podrzędne mogą przesłonić tą metodę lub ją zignorować.

Użyjmy wzorca na przykładzie. Załóżmy, że chcemy napisać kod pokazujący kroki postępowania przy wykonywaniu elementów żelbetowych na budowie, np. ścian i stropów. Na początku spójrzmy na stworzone klasy bez użycia wzorca:

public class Sciana {
    private String nazwa = "ściana";

    void wykonajElement(){
        deskowanie();
        zbrojenie();
        betonowanie();
        pielęgnacja();
    }

    public void deskowanie(){
        System.out.println("Deskowanie ramowe");
    }

    public void zbrojenie(){
        System.out.println("Pręty zbrojeniowe fi=8mm");
    }

    public void betonowanie(){
        System.out.println("Betonowanie elementu: " + nazwa);
    }

    public void pielęgnacja(){
        System.out.println("Pielęgnacja betonu");
    }
}
public class Strop {
    private String nazwa = "strop";

    void wykonajElement(){
        deskowanie();
        zbrojenie();
        betonowanie();
        pielęgnacja();
    }

    public void deskowanie(){
        System.out.println("Deskowanie dźwigarkowe");
    }

    public void zbrojenie(){
        System.out.println("Pręty zbrojeniowe fi=12mm");
    }

    public void betonowanie(){
        System.out.println("Betonowanie elementu: " + nazwa);
    }

    public void pielęgnacja(){
        System.out.println("Pielęgnacja betonu");
    }
}

Takie rozwiązanie prowadzi do kopiowania kodu. Do tego przykładu doskonale sprawdzi się omawiany wzorzec Metoda Szablonowa.

Rys 2. Diagram UML – zastosowanie wzorca Metoda Szablonowa na przykładzie.
public abstract class ElementZelbetowy {
    String nazwa;

    final void wykonajElement(){
        deskowanie();
        zbrojenie();
        betonowanie();
        pielęgnacja();
    }
    abstract void deskowanie();

    abstract void zbrojenie();

    public void betonowanie(){
        System.out.println("Betonowanie elementu: " + pobierzNazwa());
    }

    public void pielęgnacja(){
        System.out.println("Pielęgnacja betonu");
    }

    public String pobierzNazwa(){
        return nazwa;
    }
}
public class Sciana extends ElementZelbetowy{

    public Sciana(){
        nazwa = "ściana";
    }

    @Override
    void deskowanie() {
        System.out.println("Deskowanie ramowe");
    }

    @Override
    void zbrojenie() {
        System.out.println("Pręty zbrojeniowe fi=8mm");
    }
}
public class Strop extends ElementZelbetowy{

    public Strop(){
        nazwa = "strop";
    }

    @Override
    void deskowanie() {
        System.out.println("Deskowanie dźwigarkowe");
    }

    @Override
    void zbrojenie() {
        System.out.println("Pręty zbrojeniowe fi=12mm");
    }
}

ElementŻelbetowy jest klasą abstrakcyjną, po której dziedziczą klasy rzeczywiste – Ściana i Strop. W tym przykładzie Metodą Szablonową jest metoda wykonaj element, która zawiera algorytm, w jaki sposób wykonywać element żelbetowy. Dzięki zastosowaniu wzorca z łatwością możemy dodawać nowe elementy np. słup, belka itp.