Menu
Coddy logo textTech

Schablonenmethodenmuster

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

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

Das Muster verwendet eine abstrakte Klasse mit einer Vorlagenmethode, die eine Folge von Schritten aufruft. Einige Schritte haben Standardimplementierungen, während andere abstrakt sind und von Unterklassen implementiert werden müssen:

abstract class DataProcessor {
    // Template-Methode – 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");
    }
}

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 typischerweise als final markiert, um zu verhindern, dass Unterklassen die Struktur des Algorithmus verändern. Beim Aufruf führt sie für alle Unterklassen dieselbe Abfolge aus:

DataProcessor csv = new CSVProcessor();
csv.process();
// Ausgabe:
// CSV-Datei lesen
// CSV-Daten parsen
// Speichern am Standardort

Das Template-Method-Muster ist ideal, wenn du Algorithmen hast, die dieselbe Struktur aufweisen, sich aber in bestimmten Schritten unterscheiden. Es fördert die Wiederverwendung von Code, indem gemeinsame Logik in der Basisklasse platziert wird und gleichzeitig eine Anpassung durch Vererbung ermöglicht wird.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Dokumentgenerierungssystem mit dem Template Method Pattern! Du erstellst ein Framework, in dem verschiedene Dokumenttypen (Berichte und Rechnungen) demselben Generierungsprozess folgen, aber bestimmte Schritte anpassen. Das ist ideal für Szenarien, in denen der allgemeine Ablauf feststeht, die Details jedoch je nach Dokumenttyp variieren.

Du organisierst deinen Code auf vier Dateien verteilt:

  • DocumentGenerator.java: Erstelle die abstrakte Basisklasse, die die Template-Methode definiert. Deine DocumentGenerator-Klasse sollte Folgendes enthalten:

    Eine final-Methode namens generateDocument(), die das Grundgerüst des Algorithmus definiert, indem sie drei Schritte in dieser Reihenfolge 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: Erstelle eine konkrete Unterklasse zum Generieren von Berichten. Sie sollte über ihren Konstruktor einen Berichtstitel (String) entgegennehmen.

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

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

    Verwende den geerbten Standard-Footer.

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

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

    Die Methode createBody() gibt in einer Zeile Customer: [name] und in der nächsten Zeile Amount Due: $[amount] aus (formatiere den Betrag mit zwei Dezimalstellen).

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

  • Main.java: Führe dein Template-Method-System zusammen! Du erhältst drei Eingaben: einen Berichtstitel (String), einen Kundennamen (String) und einen Rechnungsbetrag (double).

    Erstelle einen ReportGenerator mit dem Titel und rufe generateDocument() auf. Gib zur Trennung eine leere Zeile aus. Erstelle anschließend einen InvoiceGenerator mit dem Kundennamen und dem Betrag und rufe generateDocument() auf.

Du erhältst drei Eingaben in dieser Reihenfolge: Berichtstitel (String), Kundenname (String) und Rechnungsbetrag (double).

Bei den Eingaben Q4 Sales, Acme Corp und 1500.00 würde deine Ausgabe beispielsweise folgendermaßen aussehen:

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

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

Beachte, wie beide Dokumenttypen demselben dreistufigen Prozess folgen, der in der Template-Methode definiert ist, aber die einzelnen Schritte jeweils unterschiedlich anpassen. ReportGenerator verwendet den Standard-Footer, während InvoiceGenerator einen eigenen bereitstellt. Das ist die Stärke von Hook-Methoden im Template Method Pattern!

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 leere Zeile zur Trennung aus
        
        // TODO: Erstelle einen InvoiceGenerator mit Kundenname und 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

Übe selbstständig: Online-Java-Compiler