Menu
Coddy logo textTech

Factory-Muster

Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 72 von 91.

Das Factory Pattern ist ein Muster zur Objekterzeugung, das die Erstellung von Objekten an eine separate Klasse oder Methode delegiert. Anstatt new direkt in deinem gesamten Code zu verwenden, bittest du eine Factory, Objekte für dich zu erstellen.

Dieses Muster ist besonders nützlich, wenn du mehrere verwandte Klassen hast, die eine gemeinsame Schnittstelle teilen, und du anhand einer Bedingung entscheiden möchtest, welche davon instanziiert werden soll. Betrachte ein Benachrichtigungssystem, das Nachrichten über verschiedene Kanäle senden kann:

<?php
interface Notification {
    public function send(string $message): string;
}

class EmailNotification implements Notification {
    public function send(string $message): string {
        return "Email: $message";
    }
}

class SmsNotification implements Notification {
    public function send(string $message): string {
        return "SMS: $message";
    }
}

Ohne eine Factory würdest du überall if-Anweisungen und new-Aufrufe verstreuen. Die Factory zentralisiert diese Logik:

<?php
class NotificationFactory {
    public static function create(string $type): Notification {
        return match($type) {
            'email' => new EmailNotification(),
            'sms' => new SmsNotification(),
            default => throw new InvalidArgumentException("Unknown type: $type")
        };
    }
}

$notification = NotificationFactory::create('email');
echo $notification->send('Hello!');

Ausgabe:

Email: Hello!

Der entscheidende Vorteil besteht darin, dass dein Code von der Schnittstelle Notification und nicht von konkreten Klassen abhängt. Wenn du später eine Klasse PushNotification hinzufügst, musst du nur die Factory aktualisieren. Der gesamte Code, der die Factory verwendet, erhält automatisch Zugriff auf den neuen Typ, ohne dass Änderungen erforderlich sind.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Dokumentgeneratorsystem mit dem Fabrikmuster. Verschiedene Dokumenttypen (PDF, HTML, Klartext) verwenden eine gemeinsame Schnittstelle, erzeugen aber unterschiedliche Ausgaben: ein perfektes Szenario, um die Objekterstellung in einer Factory zu zentralisieren.

Du organisierst deinen Code auf vier Dateien verteilt:

  • Document.php: Erstelle eine Document-Schnittstelle, die den Vertrag definiert, den alle Dokumenttypen einhalten müssen. Sie sollte eine einzige Methode render(string $content): string besitzen, die Inhalte entgegennimmt und die formatierten Dokumentausgaben zurückgibt.
  • Documents.php: Binde die Document-Schnittstelle ein und erstelle drei Klassen, die sie implementieren:
    • PdfDocument: Die Methode render() gibt "PDF: [content]" zurück
    • HtmlDocument: Die Methode render() gibt "<html>[content]</html>" zurück
    • TextDocument: Die Methode render() gibt "TXT: [content]" zurück
  • DocumentFactory.php: Binde die Documents-Datei ein und erstelle eine DocumentFactory-Klasse mit einer statischen Methode create(string $type): Document. Diese Methode sollte match verwenden, um abhängig vom Typ das passende Dokumentobjekt zurückzugeben:
    • "pdf" gibt ein neues PdfDocument zurück
    • "html" gibt ein neues HtmlDocument zurück
    • "text" gibt ein neues TextDocument zurück
    • Bei jedem anderen Typ soll eine InvalidArgumentException mit der Nachricht "Unknown document type: [type]" ausgelöst werden
  • main.php: Binde die DocumentFactory-Datei ein. Du erhältst zwei Eingaben: einen Dokumenttyp und den zu rendernden Inhalt.

    Verwende die Factory, um den passenden Dokumenttyp zu erstellen, rufe anschließend seine Methode render() mit dem Inhalt auf und gib das Ergebnis aus.

    Gib in einer neuen Zeile "Factory benefit: Adding new types only requires updating the factory" aus, um hervorzuheben, warum dieses Muster wertvoll ist.

Das Fabrikmuster hält deinen Code flexibel. Wenn du später ein MarkdownDocument hinzufügen musst, aktualisierst du nur die Factory, während der gesamte bestehende Code unverändert weiter funktioniert.

Probier es selbst

<?php
require_once 'DocumentFactory.php';

// Eingabe lesen
$type = trim(fgets(STDIN));
$content = trim(fgets(STDIN));

// TODO: Verwende DocumentFactory, um den entsprechenden Dokumenttyp zu erstellen
// TODO: Rufe die render()-Methode mit dem Inhalt auf und gib das Ergebnis aus
// TODO: On a new line, print "Factory benefit: Adding new types only requires updating the factory"

?>
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-PHP-Compiler