Menu
Coddy logo textTech

Template-Method-Muster

Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 78 von 91.

Das Template Method Pattern ist ein Verhaltensmuster, das das Skelett eines Algorithmus in einer Basisklasse definiert und es Unterklassen ermöglicht, bestimmte Schritte zu überschreiben, ohne die Gesamtstruktur zu ändern. Die Basisklasse steuert den Ablauf, während Unterklassen einzelne Teile anpassen.

Erwägen Sie die Erstellung verschiedener Arten von Dokumenten.

Jedes Dokument folgt demselben Prozess: Kopfzeile erstellen, Inhalt hinzufügen, Fußzeile erstellen. Aber die Besonderheiten jedes Schritts variieren je nach Dokumenttyp. Die Template-Methode definiert diese Sequenz, während Unterklassen die Details implementieren.

<?php
abstract class DocumentGenerator {
    // Die Template-Methode - definiert die Struktur des Algorithmus
    public final function generate(): string {
        $output = $this->createHeader();
        $output .= $this->createContent();
        $output .= $this->createFooter();
        return $output;
    }
    
    // Schritte, die von Unterklassen implementiert werden müssen
    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();

Ausgabe:

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

Beachten Sie das Schlüsselwort final bei der Template-Methode. Dies verhindert, dass Unterklassen die Struktur des Algorithmus ändern. Das Muster ist ideal, wenn Sie mehrere Klassen haben, die demselben Workflow folgen, sich aber in den Implementierungsdetails unterscheiden. Das Hinzufügen eines neuen Dokumenttyps bedeutet das Erstellen einer neuen Unterklasse, ohne den bestehenden Code zu berühren.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Berichtserstellungssystem mit dem Template Method Pattern erstellen. Verschiedene Arten von Berichten folgen derselben Struktur — ein Titelabschnitt, ein Datenabschnitt und ein Zusammenfassungsabschnitt — aber jeder Berichtstyp formatiert diese Abschnitte unterschiedlich. Die Template-Methode wird diesen Workflow definieren, während Unterklassen jeden Schritt anpassen.

Sie werden Ihren Code über vier Dateien organisieren:

  • ReportGenerator.php — Erstellen Sie eine abstrakte Klasse ReportGenerator, die das Skelett des Berichtserstellungsalgorithmus definiert. Ihre Klasse sollte:
    • Einen Berichtstitel in ihrem Konstruktor akzeptieren (verwenden Sie Constructor Promotion)
    • Eine final öffentliche Methode generate(): string haben, die drei Schritte in der folgenden Reihenfolge aufruft: createTitle(), createBody() und createSummary(), und deren Ergebnisse verkettet
    • Drei abstrakte geschützte Methoden deklarieren, die Unterklassen implementieren müssen: createTitle(): string, createBody(): string und createSummary(): string
  • HtmlReport.php — Binden Sie die Datei ReportGenerator ein und erstellen Sie eine Klasse HtmlReport, die diese erweitert. Dieser Bericht formatiert die Ausgabe als HTML:
    • createTitle() gibt "<h1>" . $this->title . "</h1>" zurück
    • createBody() gibt "<p>Report data goes here</p>" zurück
    • createSummary() gibt "<footer>End of report</footer>" zurück
  • PlainTextReport.php — Binden Sie die Datei ReportGenerator ein und erstellen Sie eine Klasse PlainTextReport, die diese erweitert. Dieser Bericht verwendet eine einfache Textformatierung:
    • createTitle() gibt "### " . $this->title . " ###\n" zurück
    • createBody() gibt "Report data goes here\n" zurück
    • createSummary() gibt "--- End of report ---" zurück
  • main.php — Binden Sie beide Berichtsdateien ein. Sie erhalten zwei Eingaben: einen Berichtstyp ("html" oder "text") und einen Berichtstitel.

    Erstellen Sie basierend auf dem Berichtstyp den entsprechenden Berichtsgenerator mit dem angegebenen Titel. Rufen Sie generate() auf und geben Sie den vollständigen Bericht aus.

Das Template Method Pattern stellt sicher, dass alle Berichte derselben dreistufigen Struktur folgen, während es jedem Berichtstyp ermöglicht, seine Abschnitte individuell zu formatieren. Das Schlüsselwort final bei generate() verhindert, dass Unterklassen die Abfolge des Algorithmus ändern — sie können nur einzelne Schritte anpassen.

Spickzettel

Das Template Method Pattern (Schablonenmethode) definiert das Skelett eines Algorithmus in einer Basisklasse und ermöglicht es Unterklassen, bestimmte Schritte zu überschreiben, ohne die Gesamtstruktur zu ändern.

Die Basisklasse enthält eine Schablonenmethode, die den Ablauf steuert. Diese Methode ist normalerweise als final markiert, um zu verhindern, dass Unterklassen die Struktur des Algorithmus verändern.

Unterklassen implementieren abstrakte Methoden, um einzelne Schritte des Algorithmus anzupassen.

<?php
abstract class DocumentGenerator {
    // Schablonenmethode - definiert die Algorithmusstruktur
    public final function generate(): string {
        $output = $this->createHeader();
        $output .= $this->createContent();
        $output .= $this->createFooter();
        return $output;
    }
    
    // Abstrakte Schritte, die von Unterklassen implementiert werden müssen
    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>";
    }
}

$html = new HtmlDocument();
echo $html->generate();

Wesentliche Merkmale:

  • Die Schablonenmethode ist als final markiert, um eine Änderung der Algorithmusstruktur zu verhindern
  • Abstrakte Methoden definieren Anpassungspunkte für Unterklassen
  • Ideal, wenn mehrere Klassen demselben Workflow folgen, sich aber in den Implementierungsdetails unterscheiden
  • Das Hinzufügen neuer Varianten erfordert lediglich das Erstellen neuer Unterklassen, ohne bestehenden Code zu ändern

Probier es selbst

<?php

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

// Eingabe lesen
$reportType = trim(fgets(STDIN));
$reportTitle = trim(fgets(STDIN));

// TODO: Basierend auf dem Berichtstyp ("html" oder "text"),
// erstelle den entsprechenden Berichtsgenerator mit dem angegebenen Titel

// TODO: Rufe generate() auf und gib den vollständigen Bericht aus

?>
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung