Menu
Coddy logo textTech

Factory Pattern

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

Das Factory-Muster ist ein Erzeugungsmuster, das die Objekterzeugung an eine separate Methode oder Klasse delegiert. Anstatt new direkt in Ihrem Code zu verwenden, lassen Sie eine Factory Objekte für Sie erstellen. Dies zentralisiert die Erzeugungslogik und macht Ihren Code flexibler.

Stellen Sie sich ein Szenario vor, in dem Sie verschiedene Arten von Dokumenten erstellen müssen. Ohne eine Factory wird Ihr Code eng an spezifische Klassen gekoppelt:

// Ohne Factory – verteilte Erstellungslogik
IDocument doc;
if (type == "pdf")
    doc = new PdfDocument();
else if (type == "word")
    doc = new WordDocument();

Eine Factory kapselt diese Entscheidungsfindung 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")
        };
    }
}

Jetzt 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 wird geöffnet

Das Factory-Pattern glänzt, wenn Sie später neue Typen hinzufügen müssen. Das Hinzufügen eines SpreadsheetDocument erfordert nur Änderungen in der Factory, nicht überall dort, wo Dokumente erstellt werden. Diese Trennung macht Ihre Codebasis einfacher zu warten und zu testen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Benachrichtigungssystem mit dem Factory-Pattern erstellen. Anstatt verschiedene Benachrichtigungstypen direkt im gesamten Code zu erstellen, zentralisieren Sie die Erstellungslogik in einer Factory-Klasse, die basierend auf einer einfachen Zeichenfolgenkennung entscheidet, welche Benachrichtigung erstellt werden soll.

Sie werden Ihren Code über drei Dateien organisieren:

  • Notification.cs: Definieren Sie ein INotification-Interface im Namespace Notifications mit einer einzigen Methode Send(string message), die einen String zurückgibt. Erstellen Sie dann drei Klassen, die dieses Interface implementieren:
    • EmailNotification - gibt "Email: {message}" zurück
    • SmsNotification - gibt "SMS: {message}" zurück
    • PushNotification - gibt "Push: {message}" zurück
  • NotificationFactory.cs: Erstellen Sie eine NotificationFactory-Klasse im selben Namespace mit einer Create(string type)-Methode, die basierend auf dem Typ-String das entsprechende INotification-Objekt zurückgibt:
    • "email" gibt eine EmailNotification zurück
    • "sms" gibt eine SmsNotification zurück
    • "push" gibt eine PushNotification zurück
    Geben Sie für jeden nicht erkannten Typ standardmäßig eine EmailNotification zurück.
  • Program.cs: Führen Sie alles zusammen, indem Sie eine Factory-Instanz erstellen und diese verwenden, um Benachrichtigungen basierend auf der Eingabe zu erstellen. Die Factory übernimmt die gesamte Entscheidungsfindung darüber, welche konkrete Klasse instanziiert werden soll.

Sie erhalten zwei Eingaben:

  • Den Benachrichtigungstyp (z. B. sms)
  • Die zu sendende Nachricht (z. B. Your order has shipped)

Verwenden Sie Ihre Factory, um den entsprechenden Benachrichtigungstyp zu erstellen, rufen Sie dann dessen Send-Methode mit der Nachricht auf und geben Sie das Ergebnis aus.

Wenn die Eingaben beispielsweise push und Meeting in 5 minutes sind, sollte die Ausgabe wie folgt lauten:

Push: Meeting in 5 minutes

Beachten Sie, dass Ihr Hauptcode niemals new EmailNotification() oder ähnliches verwendet – er fragt einfach die Factory nach dem, was er benötigt. Wenn Sie später eine SlackNotification hinzufügen, müssten Sie nur die Factory aktualisieren und nicht jede Stelle, an der Benachrichtigungen erstellt werden!

Spickzettel

Das Factory-Muster (Fabrikmuster) ist ein Erzeugungsmuster, das die Objekterstellung an eine separate Methode oder Klasse delegiert, wodurch die Erstellungslogik zentralisiert und der Code flexibler wird.

Ohne eine Factory ist die Objekterstellung verstreut und eng gekoppelt:

// Ohne Factory - verstreute Erstellungslogik
IDocument doc;
if (type == "pdf")
    doc = new PdfDocument();
else if (type == "word")
    doc = new WordDocument();

Mit einer Factory ist die Erstellungslogik an einem Ort gekapselt:

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")
        };
    }
}

Der Client-Code fordert Objekte an, ohne die konkreten Klassen zu kennen:

var factory = new DocumentFactory();
IDocument doc = factory.Create("pdf");
doc.Open();  // Opening PDF

Das Factory-Muster erleichtert das Hinzufügen neuer Typen – Änderungen sind auf die Factory isoliert und nicht über die gesamte Codebasis verteilt.

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 entsprechende Benachrichtigung zu erstellen

        // TODO: Rufe die Send-Methode auf und gib das Ergebnis 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