Menu
Coddy logo textTech

Factory-Muster

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

Das Factory-Pattern delegiert die Objekterstellung an eine separate Methode oder Klasse, sodass Sie Objekte erstellen können, ohne deren genaue Klasse anzugeben. Dies unterscheidet sich vom Factory-Konstruktor, den Sie zuvor kennengelernt haben – das Factory-Pattern ist ein Designansatz, bei dem die Erstellungslogik zentralisiert ist und basierend auf der Eingabe verschiedene Typen zurückgeben kann.

Stellen Sie sich ein Szenario vor, in dem Sie verschiedene Arten von Benachrichtigungen erstellen müssen. Anstatt dass der Client entscheidet, welche Klasse instanziiert werden soll, übernimmt eine Factory diese Entscheidung:

abstract class Notification {
  void send(String message);
}

class EmailNotification implements Notification {
  @override
  void send(String message) => print('Email: $message');
}

class SMSNotification implements Notification {
  @override
  void send(String message) => print('SMS: $message');
}

class NotificationFactory {
  static Notification create(String type) {
    switch (type) {
      case 'email':
        return EmailNotification();
      case 'sms':
        return SMSNotification();
      default:
        return EmailNotification();
    }
  }
}

void main() {
  var notification = NotificationFactory.create('sms');
  notification.send('Hello!');  // SMS: Hello!
}

Der Client-Code muss nichts über EmailNotification oder SMSNotification wissen – er fragt einfach die Factory nach einer Benachrichtigung eines bestimmten Typs. Dies macht das Hinzufügen neuer Benachrichtigungstypen einfach: Sie ändern nur die Factory, nicht jede Stelle, an der Benachrichtigungen erstellt werden.

Verwenden Sie das Factory-Pattern, wenn die Objekterstellung komplexe Logik beinhaltet, wenn Sie Implementierungsklassen vor Clients verbergen möchten oder wenn der genaue zu erstellende Typ von Laufzeitbedingungen abhängt.

challenge icon

Aufgabe

Einfach

Lassen Sie uns einen Dokumentengenerator mit dem Factory-Pattern erstellen! Sie werden ein System entwickeln, das verschiedene Arten von Dokumenten (Berichte, Rechnungen und Briefe) über eine zentrale Factory erzeugt, sodass der Client-Code die spezifischen Dokumentklassen nicht kennen muss.

Sie werden Ihren Code in zwei Dateien organisieren:

  • document_factory.dart: Erstellen Sie hier Ihr Dokumentensystem:
    • Eine abstrakte Klasse Document mit einer Methode generate(String content), die einen String zurückgibt
    • Drei konkrete Klassen, die Document implementieren:
      • Report - seine generate-Methode gibt === REPORT ===\n[content]\n============= zurück
      • Invoice - seine generate-Methode gibt INVOICE\n--------\n[content]\nTotal Due zurück
      • Letter - seine generate-Methode gibt Dear Reader,\n[content]\nSincerely zurück
    • Eine DocumentFactory-Klasse mit einer statischen Methode create(String type), die das entsprechende Document basierend auf dem Typ-String zurückgibt: "report", "invoice" oder "letter". Geben Sie für jeden unbekannten Typ standardmäßig ein Letter-Objekt zurück
  • main.dart: Importieren Sie Ihre Dokument-Factory und demonstrieren Sie, wie die Factory verschiedene Dokumenttypen erstellt, ohne dass der Client die konkreten Klassen kennen muss:
    • Verwenden Sie die Factory, um einen Bericht zu erstellen, und geben Sie das Ergebnis der Generierung mit dem Inhalt Sales increased by 25% aus
    • Geben Sie eine Leerzeile aus
    • Verwenden Sie die Factory, um eine Rechnung zu erstellen, und geben Sie das Ergebnis der Generierung mit dem Inhalt Widget x3 - $150 aus
    • Geben Sie eine Leerzeile aus
    • Verwenden Sie die Factory, um einen Brief zu erstellen, und geben Sie das Ergebnis der Generierung mit dem Inhalt Thank you for your order aus

Beachten Sie, dass Ihre Hauptdatei nur mit der Factory und dem abstrakten Typ Document interagiert – sie erstellt niemals direkt Report-, Invoice- oder Letter-Objekte!

Erwartete Ausgabe:

=== REPORT ===
Sales increased by 25%
=============

INVOICE
--------
Widget x3 - $150
Total Due

Dear Reader,
Thank you for your order
Sincerely

Spickzettel

Das Factory-Muster delegiert die Objekterstellung an eine separate Methode oder Klasse, was es Ihnen ermöglicht, Objekte zu erstellen, ohne deren genaue Klasse anzugeben. Die Erstellungslogik ist zentralisiert und kann basierend auf der Eingabe verschiedene Typen zurückgeben.

Grundstruktur des Factory-Musters:

abstract class Notification {
  void send(String message);
}

class EmailNotification implements Notification {
  @override
  void send(String message) => print('Email: $message');
}

class SMSNotification implements Notification {
  @override
  void send(String message) => print('SMS: $message');
}

class NotificationFactory {
  static Notification create(String type) {
    switch (type) {
      case 'email':
        return EmailNotification();
      case 'sms':
        return SMSNotification();
      default:
        return EmailNotification();
    }
  }
}

void main() {
  var notification = NotificationFactory.create('sms');
  notification.send('Hello!');  // SMS: Hello!
}

Der Client-Code interagiert nur mit der Factory und dem abstrakten Typ, nicht mit den konkreten Implementierungsklassen. Dies macht das Hinzufügen neuer Typen einfach – Sie müssen nur die Factory anpassen.

Verwenden Sie das Factory-Muster, wenn:

  • Die Objekterstellung komplexe Logik beinhaltet
  • Sie Implementierungsklassen vor Clients verbergen möchten
  • Der genaue zu erstellende Typ von Laufzeitbedingungen abhängt

Probier es selbst

import 'document_factory.dart';

void main() {
  // TODO: Verwende DocumentFactory.create(), um einen Bericht zu erstellen
  // Gib dann das Ergebnis der Generierung mit dem Inhalt "Sales increased by 25%" aus
  
  // TODO: Gib eine Leerzeile aus
  
  // TODO: Verwende DocumentFactory.create(), um eine Rechnung zu erstellen
  // Gib dann das Ergebnis der Generierung mit dem Inhalt "Widget x3 - \$150" aus
  
  // TODO: Gib eine Leerzeile aus
  
  // TODO: Verwende DocumentFactory.create(), um einen Brief zu erstellen
  // Gib dann das Ergebnis der Generierung mit dem Inhalt "Thank you for your order" aus
}
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