Menu
Coddy logo textTech

Template-Method-Muster

Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy — Lektion 59 von 70.

Das Template-Method-Muster 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 abgeleitete Klassen einzelne Teile anpassen.

Dieses Muster verwendet Vererbung und abstrakte Methoden. Die Basisklasse enthält eine „Template-Methode“, die eine Abfolge von Schritten aufruft, von denen einige abstrakt sind und von Unterklassen implementiert werden müssen:

public abstract class DataProcessor
{
    // Template-Methode - definiert die Struktur des Algorithmus
    public void Process()
    {
        ReadData();
        ProcessData();
        SaveData();
    }
    
    protected abstract void ReadData();
    protected abstract void ProcessData();
    protected virtual void SaveData() => Console.WriteLine("Saving to default location");
}

public class CsvProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading CSV file");
    protected override void ProcessData() => Console.WriteLine("Parsing CSV data");
}

public class JsonProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading JSON file");
    protected override void ProcessData() => Console.WriteLine("Parsing JSON data");
    protected override void SaveData() => Console.WriteLine("Saving to cloud");
}

Jede Unterklasse stellt ihre eigene Implementierung bereit, während die Basisklasse die Reihenfolge der Operationen erzwingt:

DataProcessor csv = new CsvProcessor();
csv.Process();
// CSV-Datei lesen
// CSV-Daten parsen
// Am Standardspeicherort speichern

DataProcessor json = new JsonProcessor();
json.Process();
// JSON-Datei lesen
// JSON-Daten parsen
// In der Cloud speichern

Das Template-Method-Muster ist ideal, wenn mehrere Klassen dieselbe Algorithmusstruktur teilen, sich aber in spezifischen Schritten unterscheiden. Es fördert die Wiederverwendung von Code, indem es die gemeinsame Logik in der Basisklasse platziert und gleichzeitig Flexibilität durch überschreibbare Methoden ermöglicht.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Berichtserstellungssystem mit dem Template Method Pattern erstellen. Verschiedene Arten von Berichten (wie Verkaufsberichte und Inventarberichte) teilen die gleiche Gesamtstruktur – sie müssen alle Daten sammeln, formatieren und das Ergebnis ausgeben – aber jeder Berichtstyp verarbeitet diese Schritte unterschiedlich.

Sie werden Ihren Code über drei Dateien organisieren:

  • ReportGenerator.cs: Erstellen Sie eine abstrakte Klasse ReportGenerator im Namespace Reporting. Diese Basisklasse definiert das Skelett des Berichtserstellungsalgorithmus durch eine Template-Methode namens Generate(). Die Methode sollte drei Schritte nacheinander aufrufen: GatherData(), FormatReport() und OutputReport(). Machen Sie GatherData() und FormatReport() abstrakt (jeder Berichtstyp wird diese unterschiedlich implementieren), während OutputReport() eine virtuelle Methode mit einer Standardimplementierung sein sollte, die Sending to default printer ausgibt.
  • ConcreteReports.cs: Erstellen Sie zwei konkrete Berichtsklassen im selben Namespace, die von ReportGenerator erben:
    • SalesReport – implementiert GatherData(), um Collecting sales data from database auszugeben, und FormatReport(), um Formatting as sales summary auszugeben.
    • InventoryReport – implementiert GatherData(), um Scanning warehouse inventory auszugeben, FormatReport(), um Formatting as inventory list auszugeben, und überschreibt OutputReport(), um Sending to warehouse manager auszugeben.
  • Program.cs: Führen Sie alles zusammen, indem Sie Berichtsinstanzen erstellen und diese generieren. Die Template-Methode stellt sicher, dass jeder Bericht demselben dreistufigen Prozess folgt, aber das spezifische Verhalten jedes Schritts variiert je nach Berichtstyp.

Sie erhalten eine Eingabe:

  • Den Berichtstyp: sales oder inventory

Erstellen Sie den entsprechenden Berichtsgenerator basierend auf der Eingabe und rufen Sie dessen Methode Generate() auf.

Wenn die Eingabe beispielsweise sales ist, sollte die Ausgabe wie folgt aussehen:

Collecting sales data from database
Formatting as sales summary
Sending to default printer

Wenn die Eingabe inventory ist, sollte die Ausgabe wie folgt aussehen:

Scanning warehouse inventory
Formatting as inventory list
Sending to warehouse manager

Beachten Sie, wie beide Berichte genau derselben Algorithmusstruktur folgen (Sammeln, Formatieren, Ausgeben), aber die Implementierung jedes Schritts angepasst ist. Der SalesReport verwendet das Standard-Ausgabeverhalten, während InventoryReport es überschreibt – dies zeigt, wie das Template Method Pattern es Ihnen ermöglicht zu steuern, welche Schritte zwingend überschrieben werden müssen und welche optional angepasst werden können!

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 „Template-Methode“, die eine Abfolge von Schritten aufruft. Einige Schritte sind abstrakt (müssen von Unterklassen implementiert werden), während andere virtuell sein können (optional zu überschreiben):

public abstract class DataProcessor
{
    // Template-Methode - definiert die Algorithmusstruktur
    public void Process()
    {
        ReadData();
        ProcessData();
        SaveData();
    }
    
    protected abstract void ReadData();
    protected abstract void ProcessData();
    protected virtual void SaveData() => Console.WriteLine("Saving to default location");
}

Unterklassen stellen ihre eigenen Implementierungen bereit, während die Basisklasse die Reihenfolge der Operationen erzwingt:

public class CsvProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading CSV file");
    protected override void ProcessData() => Console.WriteLine("Parsing CSV data");
}

public class JsonProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading JSON file");
    protected override void ProcessData() => Console.WriteLine("Parsing JSON data");
    protected override void SaveData() => Console.WriteLine("Saving to cloud");
}

Verwendung:

DataProcessor csv = new CsvProcessor();
csv.Process();
// Reading CSV file
// Parsing CSV data
// Saving to default location

DataProcessor json = new JsonProcessor();
json.Process();
// Reading JSON file
// Parsing JSON data
// Saving to cloud

Das Template Method Pattern ist ideal, wenn mehrere Klassen dieselbe Algorithmusstruktur teilen, sich aber in bestimmten Schritten unterscheiden. Es fördert die Wiederverwendung von Code, indem es die gemeinsame Logik in der Basisklasse platziert und gleichzeitig Flexibilität durch überschreibbare Methoden ermöglicht.

Probier es selbst

using System;
using Reporting;

class Program
{
    public static void Main(string[] args)
    {
        string reportType = Console.ReadLine();
        
        // TODO: Erstelle den entsprechenden Berichtsgenerator basierend auf reportType
        // Wenn reportType "sales" ist, erstelle einen SalesReport
        // Wenn reportType "inventory" ist, erstelle einen InventoryReport
        // Rufe dann die Methode Generate() für den Bericht 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