Menu
Coddy logo textTech

Template-Method-Muster

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy — Lektion 73 von 87.

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. Stellen Sie es sich wie ein Rezept vor: Der allgemeine Kochvorgang bleibt gleich, aber einzelne Zutaten oder Techniken können variieren.

Das Muster verwendet eine abstrakte Klasse mit einer Template-Methode, die eine Abfolge von Schritten aufruft. Einige Schritte besitzen Standardimplementierungen, während andere abstrakt sind und von Unterklassen implementiert werden müssen:

abstract class DataProcessor {
    // Template-Methode - definiert die Algorithmusstruktur
    public final void process() {
        readData();
        processData();
        saveData();
    }
    
    abstract void readData();
    abstract void processData();
    
    // Standardimplementierung (Hook-Methode)
    void saveData() {
        System.out.println("Saving to default location");
    }
}

class CSVProcessor extends DataProcessor {
    void readData() {
        System.out.println("Reading CSV file");
    }
    
    void processData() {
        System.out.println("Parsing CSV data");
    }
}

class XMLProcessor extends DataProcessor {
    void readData() {
        System.out.println("Reading XML file");
    }
    
    void processData() {
        System.out.println("Parsing XML data");
    }
}

Die Template-Methode wird normalerweise als final markiert, um zu verhindern, dass Unterklassen die Struktur des Algorithmus ändern. Wenn sie aufgerufen wird, führt sie für alle Unterklassen dieselbe Sequenz aus:

DataProcessor csv = new CSVProcessor();
csv.process();
// Ausgabe:
// CSV-Datei wird gelesen
// CSV-Daten werden geparst
// Speichern am Standardspeicherort

Das Template-Method-Pattern ist ideal, wenn Sie Algorithmen haben, die dieselbe Struktur teilen, sich aber in spezifischen Schritten unterscheiden. Es fördert die Wiederverwendung von Code, indem es die gemeinsame Logik in der Basisklasse platziert, während Anpassungen durch Vererbung ermöglicht werden.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Dokumentenerstellungssystem mit dem Template Method Pattern erstellen! Sie werden ein Framework entwickeln, in dem verschiedene Dokumenttypen (Berichte und Rechnungen) demselben Erstellungsprozess folgen, aber spezifische Schritte anpassen. Dies ist ideal für Szenarien, in denen der gesamte Workflow festgelegt ist, die Details jedoch je nach Dokumenttyp variieren.

Sie werden Ihren Code in vier Dateien organisieren:

  • DocumentGenerator.java: Erstellen Sie die abstrakte Basisklasse, die die Template-Methode definiert. Ihr DocumentGenerator sollte Folgendes enthalten:

    Eine final Methode namens generateDocument(), die das Algorithmus-Skelett definiert, indem sie drei Schritte nacheinander aufruft: createHeader(), createBody() und createFooter().

    Zwei abstrakte Methoden: createHeader() und createBody(), die von Unterklassen implementiert werden müssen.

    Eine Hook-Methode createFooter() mit einer Standardimplementierung, die --- End of Document --- ausgibt.

  • ReportGenerator.java: Erstellen Sie eine konkrete Unterklasse zum Generieren von Berichten. Sie sollte einen Berichtstitel (String) über ihren Konstruktor entgegennehmen.

    Die Methode createHeader() gibt === REPORT: [title] === aus.

    Die Methode createBody() gibt Report content goes here... aus.

    Verwenden Sie den geerbten Standard-Footer.

  • InvoiceGenerator.java: Erstellen Sie eine weitere konkrete Unterklasse zum Generieren von Rechnungen. Sie sollte einen Kundennamen (String) und einen Betrag (double) über ihren Konstruktor entgegennehmen.

    Die Methode createHeader() gibt *** INVOICE *** aus.

    Die Methode createBody() gibt Customer: [name] in einer Zeile aus, gefolgt von Amount Due: $[amount] in der nächsten Zeile (formatieren Sie den Betrag auf zwei Dezimalstellen).

    Überschreiben Sie createFooter(), um Thank you for your business! auszugeben.

  • Main.java: Führen Sie Ihr Template-Methoden-System zusammen! Sie erhalten drei Eingaben: einen Berichtstitel (String), einen Kundennamen (String) und einen Rechnungsbetrag (double).

    Erstellen Sie einen ReportGenerator mit dem Titel und rufen Sie generateDocument() auf. Geben Sie eine Leerzeile zur Trennung aus. Erstellen Sie dann einen InvoiceGenerator mit dem Kundennamen und dem Betrag und rufen Sie generateDocument() auf.

Sie erhalten drei Eingaben in der folgenden Reihenfolge: Berichtstitel (String), Kundenname (String) und Rechnungsbetrag (double).

Zum Beispiel, mit den Eingaben Q4 Sales, Acme Corp und 1500.00, wäre Ihre Ausgabe:

=== REPORT: Q4 Sales ===
Report content goes here...
--- End of Document ---

*** INVOICE ***
Customer: Acme Corp
Amount Due: $1500.00
Thank you for your business!

Beachten Sie, wie beide Dokumenttypen demselben dreistufigen Prozess folgen, der in der Template-Methode definiert ist, aber jeder die Schritte unterschiedlich anpasst. Der ReportGenerator verwendet den Standard-Footer, während der InvoiceGenerator seinen eigenen bereitstellt – das ist die Stärke von Hook-Methoden im Template Method Pattern!

Spickzettel

Das Template Method Pattern (Schablonenmethode) 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.

Das Muster verwendet eine abstrakte Klasse mit einer Schablonenmethode, die eine Abfolge von Schritten aufruft. Einige Schritte verfügen über Standardimplementierungen, während andere abstrakt sind und von Unterklassen implementiert werden müssen:

abstract class DataProcessor {
    // Schablonenmethode - definiert die Struktur des Algorithmus
    public final void process() {
        readData();
        processData();
        saveData();
    }
    
    abstract void readData();
    abstract void processData();
    
    // Standardimplementierung (Hook-Methode)
    void saveData() {
        System.out.println("Saving to default location");
    }
}

Konkrete Unterklassen implementieren die abstrakten Methoden:

class CSVProcessor extends DataProcessor {
    void readData() {
        System.out.println("Reading CSV file");
    }
    
    void processData() {
        System.out.println("Parsing CSV data");
    }
}

Die Schablonenmethode ist als final markiert, um zu verhindern, dass Unterklassen die Struktur des Algorithmus ändern. Wenn sie aufgerufen wird, führt sie für alle Unterklassen dieselbe Sequenz aus:

DataProcessor csv = new CSVProcessor();
csv.process();
// Ausgabe:
// Reading CSV file
// Parsing CSV data
// Saving to default location

Hauptmerkmale:

  • Die Schablonenmethode ist final und definiert die Struktur des Algorithmus
  • Abstrakte Methoden müssen von Unterklassen implementiert werden
  • Hook-Methoden bieten Standardimplementierungen, die optional überschrieben werden können
  • Fördert die Wiederverwendung von Code, indem gemeinsame Logik in der Basisklasse platziert wird

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Eingaben lesen
        String reportTitle = scanner.nextLine();
        String customerName = scanner.nextLine();
        double invoiceAmount = scanner.nextDouble();
        
        // TODO: Erstelle einen ReportGenerator mit dem Titel und rufe generateDocument() auf
        
        // TODO: Gib eine Leerzeile zur Trennung aus
        
        // TODO: Erstelle einen InvoiceGenerator mit dem Kundennamen und dem Betrag und rufe generateDocument() auf
        
    }
}
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