Menu
Coddy logo textTech

Wzorzec metody szablonowej

Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 78 z 91.

Wzorzec Template Method to behawioralny wzorzec projektowy, który definiuje szkielet algorytmu w klasie bazowej, pozwalając klasom pochodnym nadpisywać określone kroki bez zmieniania ogólnej struktury. Klasa bazowa kontroluje przebieg pracy, a klasy pochodne dostosowują poszczególne elementy.

Rozważ tworzenie różnych typów dokumentów.

Każdy dokument przechodzi przez ten sam proces: utworzenie nagłówka, dodanie treści, utworzenie stopki. Szczegóły każdego kroku różnią się jednak w zależności od typu dokumentu. Metoda szablonowa definiuje tę sekwencję, a podklasy implementują poszczególne szczegóły.

<?php
abstract class DocumentGenerator {
    // Metoda szablonowa – definiuje strukturę algorytmu
    public final function generate(): string {
        $output = $this->createHeader();
        $output .= $this->createContent();
        $output .= $this->createFooter();
        return $output;
    }
    
    // Kroki do zaimplementowania przez klasy pochodne
    abstract protected function createHeader(): string;
    abstract protected function createContent(): string;
    abstract protected function createFooter(): string;
}

class HtmlDocument extends DocumentGenerator {
    protected function createHeader(): string {
        return "<html><head></head><body>";
    }
    
    protected function createContent(): string {
        return "<p>Hello World</p>";
    }
    
    protected function createFooter(): string {
        return "</body></html>";
    }
}

class TextDocument extends DocumentGenerator {
    protected function createHeader(): string {
        return "=== DOCUMENT ===\n";
    }
    
    protected function createContent(): string {
        return "Hello World\n";
    }
    
    protected function createFooter(): string {
        return "=== END ===";
    }
}

$html = new HtmlDocument();
echo $html->generate() . "\n";

$text = new TextDocument();
echo $text->generate();

Wynik:

<html><head></head><body><p>Hello World</p></body></html>
=== DOCUMENT ===
Hello World
=== END ===

Zwróć uwagę na słowo kluczowe final w metodzie szablonowej. Zapobiega ono zmianie struktury algorytmu przez podklasy. Ten wzorzec sprawdza się idealnie, gdy masz wiele klas realizujących ten sam przepływ pracy, ale różniących się szczegółami implementacji. Dodanie nowego typu dokumentu oznacza utworzenie nowej podklasy bez ingerowania w istniejący kod.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system generowania raportów z użyciem wzorca Template Method. Różne typy raportów mają tę samą strukturę: sekcję tytułu, sekcję danych i sekcję podsumowania, ale każdy typ raportu formatuje te sekcje inaczej. Metoda szablonowa zdefiniuje ten przepływ, a podklasy dostosują poszczególne kroki.

Rozmieścisz kod w czterech plikach:

  • ReportGenerator.php: Utwórz abstrakcyjną klasę ReportGenerator, która definiuje szkielet algorytmu generowania raportu. Twoja klasa powinna:
    • Przyjmować tytuł raportu w konstruktorze (użyj promocji właściwości konstruktora)
    • Mieć publiczną metodę final generate(): string, która wywołuje kolejno trzy kroki: createTitle(), createBody() i createSummary(), łącząc ich wyniki
    • Deklarować trzy abstrakcyjne metody chronione, które podklasy muszą zaimplementować: createTitle(): string, createBody(): string i createSummary(): string
  • HtmlReport.php: Dołącz plik ReportGenerator i utwórz klasę HtmlReport, która ją rozszerza. Ten raport formatuje dane wyjściowe jako HTML:
    • createTitle() zwraca "<h1>[title]</h1>"
    • createBody() zwraca "<p>Report data goes here</p>"
    • createSummary() zwraca "<footer>End of report</footer>"
  • PlainTextReport.php: Dołącz plik ReportGenerator i utwórz klasę PlainTextReport, która ją rozszerza. Ten raport używa prostego formatowania tekstu:
    • createTitle() zwraca "### [title] ###\n"
    • createBody() zwraca "Report data goes here\n"
    • createSummary() zwraca "--- End of report ---"
  • main.php: Dołącz oba pliki raportów. Otrzymasz dwa dane wejściowe: typ raportu ("html" lub "text") oraz tytuł raportu.

    Na podstawie typu raportu utwórz odpowiedni generator raportów z podanym tytułem. Wywołaj generate() i wypisz cały raport.

Wzorzec Template Method sprawia, że wszystkie raporty mają tę samą, trzyetapową strukturę, a jednocześnie pozwala każdemu typowi raportu w unikalny sposób formatować swoje sekcje. Słowo kluczowe final w metodzie generate() uniemożliwia podklasom zmianę kolejności algorytmu. Mogą one dostosowywać wyłącznie poszczególne kroki.

Spróbuj swoich sił

<?php

require_once 'HtmlReport.php';
require_once 'PlainTextReport.php';

// Wczytaj dane wejściowe
$reportType = trim(fgets(STDIN));
$reportTitle = trim(fgets(STDIN));

// TODO: Na podstawie typu raportu ("html" lub "text"),
// utwórz odpowiedni generator raportu z podanym tytułem

// TODO: Wywołaj generate() i wypisz cały raport

?>
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator PHP online