Menu
Coddy logo textTech

Wzorzec fabryki

Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 55 z 61.

Wzorzec fabryki centralizuje tworzenie obiektów w jednej funkcji. Zamiast rozrzucać kod malloc i inicjalizacji po całym programie, wywołujesz jedną funkcję, która decyduje, co utworzyć, i zwraca gotowy do użycia obiekt.

Ten wzorzec jest szczególnie przydatny w połączeniu z polimorfizmem. Fabryka może zwracać różne typy konkretne za pomocą wspólnego wskaźnika bazowego, ukrywając przed wywołującym szczegóły tworzenia. Wywołujący prosi po prostu o „kształt”, a fabryka decyduje, czy utworzyć koło, prostokąt, czy coś innego.

Oto typowa implementacja wzorca fabryki:

typedef enum {
    SHAPE_CIRCLE,
    SHAPE_RECTANGLE
} ShapeType;

Shape* create_shape(ShapeType type) {
    switch (type) {
        case SHAPE_CIRCLE:
            return (Shape*)create_circle(5.0);
        case SHAPE_RECTANGLE:
            return (Shape*)create_rectangle(4.0, 3.0);
        default:
            return NULL;
    }
}

Fabryka przyjmuje identyfikator (zwykle wyliczenie) i używa instrukcji switch, aby określić, który konstruktor wywołać. Zwraca Shape* niezależnie od utworzonego rzeczywistego typu. Wywołujący nie musi znać Circle ani Rectangle. Po prostu pracuje z typem bazowym:

Shape* s = create_shape(SHAPE_CIRCLE);
s->draw(s);  // wywołanie polimorficzne
free_shape(s);

Ten wzorzec ułatwia dodawanie nowych typów: wystarczy dodać nową wartość wyliczeniową i nową gałąź w fabryce. Reszta kodu pozostaje bez zmian.

challenge icon

Wyzwanie

Łatwy

Zbudujmy fabrykę zwierząt: system, który tworzy różne rodzaje zwierząt za pomocą jednej funkcji fabrykującej. Zamiast rozpraszać logikę tworzenia w całym kodzie, skupisz ją w jednym miejscu, które na podstawie identyfikatora wejściowego decyduje, jaki rodzaj zwierzęcia utworzyć.

Podzielisz kod na trzy pliki:

  • pet.h: Zdefiniuj wyliczenie PetType z wartościami PET_DOG, PET_CAT i PET_BIRD. Utwórz bazową strukturę Pet, która zawiera wskaźnik na funkcję speak (przyjmującą const Pet* i niczego niezwracającą). Zadeklaruj funkcję fabrykującą create_pet, która przyjmuje PetType i zwraca Pet*, a także funkcję free_pet do sprzątania.
  • pet.c: Zdefiniuj trzy konkretne struktury zwierząt: Dog, Cat i Bird, z których każda osadza Pet jako swój pierwszy element. Zaimplementuj funkcję mówienia dla każdego typu:
    • Psy wypisują: Woof!
    • Koty wypisują: Meow!
    • Ptaki wypisują: Tweet!
    Utwórz funkcje konstruktora dla każdego rodzaju zwierzęcia, które przydzielają pamięć i konfigurują odpowiednią funkcję mówienia. Następnie zaimplementuj fabrykę create_pet: użyj instrukcji switch dla PetType, aby wywołać właściwy konstruktor i zwrócić wynik jako Pet*. Dla nieprawidłowych typów zwróć NULL. Zaimplementuj free_pet, aby zwolnić przydzieloną pamięć.
  • main.c: Wczytaj liczbę całkowitą reprezentującą rodzaj zwierzęcia (0 dla psa, 1 dla kota, 2 dla ptaka). Użyj fabryki, aby utworzyć odpowiednie zwierzę, wywołaj jego funkcję speak polimorficznie za pośrednictwem wskaźnika bazowego Pet*, a następnie zwolnij pamięć zajmowaną przez zwierzę.

Program otrzyma jedno wejście: liczbę całkowitą określającą, które zwierzę utworzyć.

Przykładowe wyjście dla wejścia 0:

Woof!

Przykładowe wyjście dla wejścia 1:

Meow!

Przykładowe wyjście dla wejścia 2:

Tweet!

Zaletą wzorca Fabryka jest to, że main.c nie musi znać struktur Dog, Cat ani Bird. Korzysta wyłącznie z bazowego typu Pet. Dodanie później nowego rodzaju zwierzęcia oznacza dodanie nowej wartości wyliczenia i nowej gałęzi w fabryce, bez zmieniania kodu, który korzysta ze zwierząt.

Spróbuj swoich sił

#include <stdio.h>
#include "pet.h"

int main(void) {
    int type;
    scanf("%d", &type);
    
    // TODO: Użyj fabryki, aby utworzyć odpowiednie zwierzę
    // Wskazówka: Rzutuj int na PetType
    
    // TODO: Wywołaj funkcję speak polimorficznie za pośrednictwem wskaźnika Pet*
    
    // TODO: Zwolnij pamięć zajmowaną przez zwierzę
    
    return 0;
}
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 C online