Menu
Coddy logo textTech

Schablonenmethodenmuster

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

Das Template-Method-Muster ist ein Verhaltensentwurfsmuster, das das Grundgerüst 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 Bestandteile anpassen.

Erwäge, verschiedene Arten von Dokumenten zu erstellen.

Jedes Dokument folgt demselben Ablauf: Kopfzeile erstellen, Inhalt hinzufügen, Fußzeile erstellen. Die Einzelheiten jedes Schritts unterscheiden sich jedoch je nach Dokumenttyp. Die Template-Methode definiert diese Reihenfolge, während Unterklassen die Details implementieren.

<?php
abstract class DocumentGenerator {
    // Die Template-Methode - definiert die Algorithmusstruktur
    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 ===

Beachte das Schlüsselwort final bei der Template-Methode. Dadurch wird verhindert, dass Unterklassen die Struktur des Algorithmus ändern. Das Muster ist ideal, wenn du mehrere Klassen hast, die denselben Arbeitsablauf befolgen, sich aber in den Implementierungsdetails unterscheiden. Das Hinzufügen eines neuen Dokumenttyps bedeutet, eine neue Unterklasse zu erstellen, ohne vorhandenen Code anzufassen.

challenge icon

Aufgabe

Einfach

Erstellen wir ein System zur Berichtserstellung mit dem Template-Method-Muster. Verschiedene Berichtstypen folgen derselben Struktur – einem Titelabschnitt, einem Datenabschnitt und einem Zusammenfassungsabschnitt –, formatieren diese Abschnitte jedoch jeweils unterschiedlich. Die Template-Methode definiert diesen Ablauf, während Unterklassen jeden Schritt anpassen.

Du organisierst deinen Code über vier Dateien:

  • ReportGenerator.php: Erstelle eine abstrakte Klasse ReportGenerator, die das Grundgerüst des Algorithmus zur Berichtserstellung definiert. Deine Klasse sollte:
    • einen Berichtstitel in ihrem Konstruktor akzeptieren (verwende Constructor Promotion)
    • eine final öffentliche Methode generate(): string besitzen, die drei Schritte in dieser Reihenfolge aufruft: createTitle(), createBody() und createSummary(), und ihre Ergebnisse verkettet
    • drei abstrakte geschützte Methoden deklarieren, die Unterklassen implementieren müssen: createTitle(): string, createBody(): string und createSummary(): string
  • HtmlReport.php: Binde die Datei ReportGenerator ein und erstelle eine Klasse HtmlReport, die davon erbt. Dieser Bericht formatiert die Ausgabe als HTML:
    • createTitle() gibt "<h1>[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: Binde die Datei ReportGenerator ein und erstelle eine Klasse PlainTextReport, die davon erbt. Dieser Bericht verwendet eine einfache Textformatierung:
    • createTitle() gibt "### [title] ###\n" zurück
    • createBody() gibt "Report data goes here\n" zurück
    • createSummary() gibt "--- End of report ---" zurück
  • main.php: Binde beide Berichtsdateien ein. Du erhältst zwei Eingaben: einen Berichtstyp ("html" oder "text") und einen Berichtstitel.

    Erstelle abhängig vom Berichtstyp den passenden Berichtsgenerator mit dem angegebenen Titel. Rufe generate() auf und gib den vollständigen Bericht aus.

Das Template-Method-Muster stellt sicher, dass alle Berichte derselben Struktur aus drei Schritten folgen, während jeder Berichtstyp seine Abschnitte auf eigene Weise formatieren kann. Das Schlüsselwort final bei generate() verhindert, dass Unterklassen die Reihenfolge des Algorithmus ändern. Sie können nur einzelne Schritte anpassen.

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 gegebenen Titel

// TODO: generate() aufrufen und den vollständigen Bericht ausgeben

?>
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

Übe selbstständig: Online-PHP-Compiler