Metoda fabrykująca zalicza się do wzorców kreacyjnych i jak sama nazwa mówi – musi coś tworzyć. Z tego wzorca korzystamy wtedy, kiedy nie mamy pewności jakie obiekty będą nam potrzebne lub potrzebujemy elastycznego, skalowalnego interfejsu do tworzenia obiektów. Metoda fabrykująca zwraca obiekty różnych klas, ale powiązanych typów.

SCHEMAT WZORCA METODY FABRYKUJĄCEJ

diagram metoda fabrykująca

Źródło: pl.wikipedia.org/wiki/Metoda_wytworcza_(wzorzec_projektowy)

OPIS WZORCA

Product – to interfejs, który implementuje konkretna klasa ConcreteProduct:

Creator – to klasa abstrakcyjna fabryki, zawiera metodę fabrykującą factoryMethod(), która będzie „coś” tworzyć:

Ta metoda musi być oczywiście abstrakcyjna, jak sama klasa – zgodnie z definicją 🙂

Konkretna fabryka ConcreteCreator implementuje metodę fabrykującą factoryMethod() do wytworzenia konkretnego produktu – new ConcreteProduct:

Oczywiście wzorzec nabierze sensu i znaczenia, kiedy będziemy rozbudowywać nasz program tworząc kolejne obiekty:

Użycie metody fabrykującej w klasie Client:

Jak widać, klasa Client wysyła żądanie do konkretnej fabryki, a nie do konkretnych produktów. Tak więc produkty zostawiamy w spokoju, a wytwarzaniem obiektów zajmuje się fabryka i metoda fabrykująca 🙂 Jest to bardzo elastyczne podejście ułatwiające rozbudowę programu, a także proces wprowadzania zmian do niego, bez naruszania logiki.

PRZYKŁAD

Dla przykładu zbudujemy menu do strony internetowej. Na początek wystarczy standardowa nawigacja w nagłówku i w stopce strony. W przyszłości będziemy mieli zamiar dodać drzewo kategorii (zapewne generowane dynamicznie) z różnymi wariantami. Dlatego zastosowanie wzorca metody fabrykującej, w tym przypadku jest jak najbardziej uzasadnione.

Myśląc o menu wyobrażamy sobie interfejs 🙂
Interfejs Menu musi posiadać metodę, która będzie zwracać linki:

Następnie tworzymy klasy, które zaimplementują interfejs Menu:
TopMenu (menu w nagłówku strony):

BottomMenu (menu w stopce strony):

Metoda getLinks() w obu klasach musi być użyta, zgodnie z definicją interfejsu i zwraca różne linki oraz kod html.

Teraz musimy stworzyć fabrykę Creator z metodą fabrykującą. Metoda factoryMethod() jest abstrakcyjna i będzie mogła w dowolny sposób implementować konkretne produkty: TopMenu i BottomMenu. W przypadku tej metody zastosujemy enkapsulację wprowadzając modyfikator dostępu protected. Konkretna metoda factoryMethod() z fabryki, „przepuszczana” jest przez funkcję navigation().

Tworzymy konkretną fabrykę TopMenuCreator, która dziedziczy po fabryce Creator metodę fabrykującą factoryMethod>(). Metoda ta zmienia swoją postać na konkretną i implementuje instancję produktu TopMenu:

Analogicznie postępujemy z klasą BottomMenuCreator:

Na koniec tworzymy plik index.php, który pozwoli nam zobaczyć efekt naszej pracy 🙂

PRZYKŁAD na GitHub →