Menu
Coddy logo textTech

Wzorzec Factory

Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 72 z 91.

Wzorzec fabryki to kreacyjny wzorzec projektowy, który deleguje tworzenie obiektów do osobnej klasy lub metody. Zamiast używać bezpośrednio new w całym kodzie, prosisz fabrykę o utworzenie obiektów.

Ten wzorzec jest szczególnie przydatny, gdy masz wiele powiązanych klas, które współdzielą wspólny interfejs, i chcesz zdecydować, którą z nich utworzyć na podstawie pewnego warunku. Rozważ system powiadomień, który może wysyłać wiadomości różnymi kanałami:

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

Bez fabryki porozrzucałbyś wszędzie instrukcje if i wywołania new. Fabryka centralizuje tę 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!');

Wynik:

Email: Hello!

Kluczową zaletą jest to, że Twój kod zależy od interfejsu Notification, a nie od konkretnych klas. Jeśli później dodasz klasę PushNotification, zaktualizujesz tylko fabrykę. Cały kod korzystający z fabryki automatycznie zyska dostęp do nowego typu bez modyfikacji.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system generowania dokumentów z użyciem wzorca Factory. Różne typy dokumentów (PDF, HTML, zwykły tekst) współdzielą wspólny interfejs, ale generują różne wyniki: to idealny scenariusz do centralizacji tworzenia obiektów w fabryce.

Rozmieścisz kod w czterech plikach:

  • Document.php: Utwórz interfejs Document, który definiuje kontrakt, którego muszą przestrzegać wszystkie typy dokumentów. Powinien zawierać jedną metodę render(string $content): string, która przyjmuje treść i zwraca sformatowany dokument.
  • Documents.php: Dołącz interfejs Document i utwórz trzy klasy, które go implementują:
    • PdfDocument: Jego metoda render() zwraca "PDF: [content]"
    • HtmlDocument: Jego metoda render() zwraca "<html>[content]</html>"
    • TextDocument: Jego metoda render() zwraca "TXT: [content]"
  • DocumentFactory.php: Dołącz plik Documents i utwórz klasę DocumentFactory ze statyczną metodą create(string $type): Document. Ta metoda powinna używać match, aby zwracać odpowiedni obiekt dokumentu w zależności od typu:
    • "pdf" zwraca nowy obiekt PdfDocument
    • "html" zwraca nowy obiekt HtmlDocument
    • "text" zwraca nowy obiekt TextDocument
    • Każdy inny typ powinien zgłaszać wyjątek InvalidArgumentException z komunikatem "Unknown document type: [type]"
  • main.php: Dołącz plik DocumentFactory. Otrzymasz dwa dane wejściowe: typ dokumentu i treść do wyrenderowania.

    Użyj fabryki, aby utworzyć odpowiedni typ dokumentu, a następnie wywołaj jego metodę render() z treścią i wypisz wynik.

    W nowej linii wypisz "Factory benefit: Adding new types only requires updating the factory", aby podkreślić, dlaczego ten wzorzec jest przydatny.

Wzorzec Factory sprawia, że kod pozostaje elastyczny. Gdy później dodasz MarkdownDocument, wystarczy zaktualizować fabrykę, a cały istniejący kod nadal będzie działać bez zmian.

Spróbuj swoich sił

<?php
require_once 'DocumentFactory.php';

// Odczytaj dane wejściowe
$type = trim(fgets(STDIN));
$content = trim(fgets(STDIN));

// TODO: Użyj DocumentFactory, aby utworzyć dokument odpowiedniego typu
// TODO: Wywołaj metodę render() z zawartością i wypisz wynik
// TODO: W nowym wierszu wypisz "Factory benefit: Adding new types only requires updating the factory"

?>
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator PHP online