Menu
Coddy logo textTech

Template-Method-Muster

Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 97 von 110.

Das Template-Method-Muster definiert das Grundgerüst eines Algorithmus in einer Basisklasse und ermöglicht es Unterklassen, bestimmte Schritte zu überschreiben, ohne die Gesamtstruktur zu ändern. Die Basisklasse steuert den Ablauf, während Unterklassen einzelne Schritte anpassen.

Dieses Muster verwendet Vererbung: Eine abstrakte Klasse definiert eine Template-Methode, die eine Abfolge von Schritten aufruft, von denen einige abstrakt sind (und von Unterklassen implementiert werden müssen) und einige Standardimplementierungen besitzen:

abstract class DataProcessor {
  // Template-Methode - definiert die Algorithmusstruktur
  void process() {
    readData();
    processData();
    saveData();
  }

  void readData();      // Abstrakt - Unterklassen müssen implementieren
  void processData();   // Abstrakt - Unterklassen müssen implementieren

  void saveData() {     // Standardimplementierung
    print('Data saved to database');
  }
}

class CsvProcessor extends DataProcessor {
  @override
  void readData() => print('Reading CSV file');

  @override
  void processData() => print('Parsing CSV rows');
}

class JsonProcessor extends DataProcessor {
  @override
  void readData() => print('Reading JSON file');

  @override
  void processData() => print('Parsing JSON objects');

  @override
  void saveData() => print('Saved to cloud storage');
}

void main() {
  var csv = CsvProcessor();
  csv.process();
  // CSV-Datei wird gelesen
  // CSV-Zeilen werden geparst
  // Daten in Datenbank gespeichert

  var json = JsonProcessor();
  json.process();
  // JSON-Datei wird gelesen
  // JSON-Objekte werden geparst
  // In Cloud-Speicher gespeichert
}

Die Methode process() ist die Vorlage – sie definiert die Reihenfolge der Vorgänge. Unterklassen implementieren readData() und processData() unterschiedlich und können optional saveData() überschreiben. Der entscheidende Vorteil besteht darin, dass die Struktur des Algorithmus über alle Implementierungen hinweg konsistent bleibt und gleichzeitig Flexibilität bei den einzelnen Schritten ermöglicht wird.

challenge icon

Aufgabe

Einfach

Lass uns ein System zur Berichtserstellung mit dem Template-Method-Muster erstellen! Du wirst ein Framework erstellen, in dem verschiedene Berichtstypen derselben übergeordneten Struktur folgen, aber jeder Berichtstyp bestimmte Schritte wie das Erfassen der Daten und das Formatieren der Ausgabe individuell gestaltet.

Du wirst deinen Code in zwei Dateien organisieren:

  • report_generator.dart: Diese Datei enthält deine abstrakte Basisklasse und konkrete Berichtsimplementierungen. Erstelle eine abstrakte Klasse ReportGenerator mit einer Template-Methode namens generate(), die den Ablauf der Berichtserstellung in dieser Reihenfolge definiert: fetchData(), analyzeData(), formatReport() und deliver(). Die Methoden fetchData() und formatReport() sollten abstrakt sein (jeder Berichtstyp behandelt sie anders), während analyzeData() standardmäßig Analyzing data... ausgeben und deliver() standardmäßig Report delivered via email. ausgeben sollte. Erstelle anschließend zwei konkrete Berichtsklassen:
    • SalesReport – sein fetchData() gibt Fetching sales data from database... aus und sein formatReport() gibt Formatting as bar charts and tables. aus.
    • InventoryReport – sein fetchData() gibt Fetching inventory levels from warehouse... aus, sein formatReport() gibt Formatting as inventory list. aus, und es überschreibt deliver(), um Report sent to warehouse manager. auszugeben.
  • main.dart: Importiere deine Datei für die Berichtserstellung und demonstriere, wie das Template-Method-Muster die Algorithmusstruktur konsistent hält und gleichzeitig Anpassungen ermöglicht. Erstelle einen SalesReport und rufe seine Methode generate() auf. Gib anschließend zur Trennung eine leere Zeile aus. Erstelle einen InventoryReport und rufe ebenfalls seine Methode generate() auf.

Beachte, wie beide Berichte demselben vierstufigen Prozess folgen, aber jeweils die für ihren spezifischen Zweck wichtigen Schritte anpassen. Der InventoryReport überschreibt sogar die standardmäßige Zustellmethode, um Berichte an einen anderen Empfänger zu senden!

Erwartete Ausgabe:

Fetching sales data from database...
Analyzing data...
Formatting as bar charts and tables.
Report delivered via email.

Fetching inventory levels from warehouse...
Analyzing data...
Formatting as inventory list.
Report sent to warehouse manager.

Probier es selbst

import 'report_generator.dart';

void main() {
  // TODO: Erstelle einen SalesReport und rufe seine generate()-Methode auf

  // TODO: Gib eine leere Zeile zur Trennung aus

  // TODO: Erstelle einen InventoryReport und rufe seine generate()-Methode 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-Dart-Compiler