Factory Pattern
Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy. Lektion 53 von 70.
Das Factory pattern ist ein Erzeugungsmuster, das die Objekterstellung an eine separate Methode oder Klasse delegiert. Anstatt new direkt in deinem Code zu verwenden, bittest du eine Factory, Objekte für dich zu erstellen. Dadurch wird die Erstellung-Logik zentralisiert und dein Code flexibler.
Stell dir ein Szenario vor, in dem du verschiedene Arten von Dokumenten erstellen musst. Ohne eine factory wird dein Code eng an bestimmte Klassen gekoppelt:
// Ohne Factory - verstreute Erstellungslogik
IDocument doc;
if (type == "pdf")
doc = new PdfDocument();
else if (type == "word")
doc = new WordDocument();Eine Factory kapselt diese Entscheidungslogik an einem Ort:
public interface IDocument
{
void Open();
}
public class PdfDocument : IDocument
{
public void Open() => Console.WriteLine("Opening PDF");
}
public class WordDocument : IDocument
{
public void Open() => Console.WriteLine("Opening Word");
}
public class DocumentFactory
{
public IDocument Create(string type)
{
return type switch
{
"pdf" => new PdfDocument(),
"word" => new WordDocument(),
_ => throw new ArgumentException("Unknown type")
};
}
}Nun fordert der Client-Code einfach an, was er benötigt, ohne die konkreten Klassen zu kennen:
var factory = new DocumentFactory();
IDocument doc = factory.Create("pdf");
doc.Open(); // PDF öffnenDas Factory-Muster glänzt, wenn du später neue Typen hinzufügen musst. Das Hinzufügen eines SpreadsheetDocument erfordert Änderungen nur in der factory und nicht überall dort, wo Dokumente erstellt werden. Diese Trennung macht deine Codebasis leichter zu warten und zu testen.
Aufgabe
EinfachErstellen wir ein Benachrichtigungssystem mithilfe des Factory-Musters. Anstatt verschiedene Benachrichtigungstypen direkt an unterschiedlichen Stellen in deinem Code zu erstellen, zentralisierst du die Erstellungslogik in einer Factory-class, die anhand eines einfachen Zeichenfolgenbezeichners entscheidet, welche Benachrichtigung erstellt werden soll.
Du organisierst deinen Code über drei Dateien:
Notification.cs: Define einINotification-interface imNotifications-namespace mit einer einzigen methodSend(string message), die eine Zeichenfolge returns. Erstelle dann drei classes, die dieses interface Implement:EmailNotification– returns"Email: {message}"SmsNotification– returns"SMS: {message}"PushNotification– returns"Push: {message}"
NotificationFactory.cs: Create eineNotificationFactory-class im selben namespace mit einerCreate(string type)-method, die die passendeINotificationbased auf dem type-String returns:"email"returns eineEmailNotification"sms"returns eineSmsNotification"push"returns einePushNotification
EmailNotification.Program.cs: Führe alles zusammen, indem du eine Factory-instance erstellst und sie verwendest, um Benachrichtigungen based auf input zu erstellen. Die Factory übernimmt die gesamte Entscheidungslogik darüber, welche konkrete class instanziiert werden soll.
Du erhältst zwei Eingaben:
- Den Benachrichtigungstyp (z. B.
sms) - Die zu sendende Nachricht (z. B.
Your order has shipped)
Verwende deine Factory, um den passenden Benachrichtigungstyp zu erstellen, rufe anschließend ihre Send-method mit der Nachricht auf und gib das result aus.
Wenn die Eingaben beispielsweise push und Meeting in 5 minutes lauten, sollte die Ausgabe folgendermaßen aussehen:
Push: Meeting in 5 minutesBeachte, dass dein Main-Code niemals new EmailNotification() oder etwas Ähnliches verwendet – er fragt die Factory einfach nach dem, was er benötigt. Wenn du später eine SlackNotification hinzufügst, musst du nur die Factory aktualisieren, nicht jede Stelle, die Benachrichtigungen erstellt!
Probier es selbst
using System;
using Notifications;
class Program
{
public static void Main(string[] args)
{
// Eingabe lesen
string type = Console.ReadLine();
string message = Console.ReadLine();
// TODO: Erstelle eine NotificationFactory-Instanz
// TODO: Verwende die Factory, um die passende Benachrichtigung zu erstellen
// TODO: Rufe die Send-Methode auf und gib das Ergebnis aus
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienNamespaces & DirektivenEinführung in Klassen & ObjekteDas 'this'-SchlüsselwortMethoden und ParameterFelder vs. EigenschaftenKonstruktorenObjekt-InitialisiererZusammenfassung - Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (:) SyntaxDas 'base'-SchlüsselwortVirtual & Override SchlüsselwörterVersiegelte KlassenDie 'object'-BasisklasseZusammenfassung – Mitarbeiter-Hierarchie7Fortgeschrittene Funktionen
OperatorüberladungIndexer (this[])ToString() überschreibenErweiterungsmethodenZusammenfassung - Benutzerdefinierte Liste10Design Patterns Teil 1
Einführung in Design PatternsThread-sicheres SingletonFactory PatternObserver Pattern (Events)Strategy Pattern2Eigenschaften & Statische Member
Automatisch implementierte EigenschaftenRead-Only- & Write-Only-EigenschaftenStatische Felder & MethodenStatische KlassenExpression-Bodied Member5Polymorphismus & Interfaces
Compile- vs. Runtime-PolymorphismusInterface vs. abstrakte KlasseMehrfache InterfacesExplizite InterfacesUpcasting & DowncastingRecap – Shape Calculator3Klassenarchitektur
Instanz- vs. statische Daten'readonly' & 'const' SchlüsselwörterBacking FieldsZusammenfassung - Bankkonto-Manager6Kapselung
ZugriffsmodifikatorenProperties zur KapselungImplementierung von Data HidingImmutability-MusterRückblick – StudierendendatenÜbe selbstständig: Online-C#-Compiler