Abstract Factory – kreacyjny wzorzec projektowy, który pozwala tworzyć rodziny powiązanych obiektów, bez określania ich konkretnych klas.
Przeznaczenie i warunki stosowania
- Udostępnia interfejs do tworzenia rodzin zależnych od siebie lub powiązanych ze sobą obiektów.
- Nie określa konkretnych klas stworzonych obiektów.
Użyj Fabryki Abstrakcyjnej kiedy twój kod musi pracować z rodzinami obiektów, ale nie chcesz aby był powiązany z konkretnymi klasami tych produktów. Klasy mogą być wcześniej nieznane, a podejście takie pozwala na łatwiejsze rozszerzenie w przyszłości.
Fabryka Abstrakcyjna a inne wzorce
Metoda Wytwórcza lub też Prototyp mogą być składowym elementem Fabryki Abstrakcyjnej. Fabryki Konkretne w Fabryce Abstrakcyjnej mogą i często są Singletonami. Wzorzec ten może też być alternatywą Fasady (Facade) kiedy jedynie chcemy ukryć przed klientem tworzenie obiektów.
Fabryka z pewnością budzi analogie do wzorca Budowniczy, który również służy do tworzenia obiektów złożonych. Z tą różnicą, że:
- Abstract Factory udostępnia produkt natychmiast, skupiając się na tworzeniu rodziny produktów.
- Builder tworzy produkt krok po kroku i zwraca go dopiero w ostatnim kroku, skupiając się na konstrukcji skomplikowanego obiektu.
W bardziej złożonych implementacjach Fabryka Abstrakcyjna może współgrać z Mostem (Bridge), który wspiera tylko konkretne implementacje Fabryki Konkretnej, ukrywając przed klientem złożoność procesu.
Życiowa Analogia
Naszym życiowo abstrakcyjnym przykładem niech będzie tym razem fabryka samochodów(Abstract Factory). Dla znacznego uproszczenia i pokazania idei załóżmy, że fabryka taka może stworzyć samochód firmy X(CF1) i Y(CF2). Produktem jest samochód osobowy sedan(CP…1) lub kombi (CP…2), zgodny z interfejsem samochodu (Product X/Y) – ma kierownicę, ma koła, ma światła ( <-przykładowe atrybuty interfejsu).
Niezależnie od wyboru fabryki konkretnej, Klient dysponuje interfejsem fabryki – Stwórz samochód sedan(CreateProductX()
) i stwórz samochód kombi (CreateProductY()
). W zależności od tego jaką fabrykę konkretną wybierze klient, takiej marki (X/Y) uzyska produkt.
Abstract Factory Struktura
- Abstract Factory – Fabryka Abstrakcyjna
- deklaracja interfejsu z metodami tworzącymi produkty abstrakcyjne
- Concrete Factory – Fabryka Konkretna
- implementacja interfejsu metod tworzących produkty konkretne
- Concrete Product – Produkt Konkretny
- implementacja interfejsu Abstract Product
- obiekt – produkt odpowiadającej mu Fabryki Konkretnej
- Abstract Product – Produkt Abstrakcyjny
- deklaracja interfejsu produktów określonego typu
- Client – Klient
- wykorzystuje jedynie interfejsy: Abstract Factory i Abstract Product
Abstract Factory Konsekwencje Stosowania
Pozytywne:
- Zachowanie spójności między produktami – korzystanie z jednego rodzaju Concrete Factory pozwala na wymuszenie ograniczenia tworzenie Produktów tylko jednej rodziny, które są zaprojektowane do wspólnego zastosowania.
- Izolacja klas konkretnych – klient jest odizolowany od klas zawierających implementację fabryk, wykorzystuje jedynie znany abstrakcyjny interfejs fabryki. Proces tworzenia produktów i samo zadanie jest ukrywane przez Fabrykę Abstrakcyjną (kapsułkowanie – encapsulation).
- Łatwe zastępowanie rodzin produktów – w celu wykorzystania innego zestawu produktów, podajemy po prostu inną Fabrykę Konkretną. Concrete Factory tworzy kompletną rodzinę produktów.
- SOLID friendly
- Z zasadą jednej odpowiedzialności – tworzenie produktu w jednym miejscu.
- Z zasadą Otwarte/Zamknięte – można dodawać nowe warianty produktów, bez konieczności zmiany kodu klienta.
Negatywne
- Utrudnia dodawanie produktów nowego rodzaju i ich obsługi – zestaw produktów reprezentowany jest w interfejsie Abstract Factory. Rozszerzenie działań fabryki i dodanie nowego produktu odbywa się przez rozszerzenie tego interfejsu. Co za tym idzie – konieczna jest modyfikacja wszystkich klas Concrete Factory i implementacja nowej metody.
Abstract Factory Implementacja
W głównych punktach, implementacja wzorca Abstract Factory, opiera się o:
- Abstract Factory – Fabryka Abstrakcyjna –
ICarFactory
- Concrete Factory – Fabryka Konkretna –
AudiFactory, BMWFactory
- Concrete Product – Produkt Konkretny –
AudiCar, BMWCar
- Abstract Product – Produkt Abstrakcyjny –
ICar
- Client – Klient – kod kliencki wykonujący operacje na Fabryce
Powyższy przykład jest oczywiście bardzo uproszczony i ma jedynie na celu ukazanie Tobie mechanizmów tworzących Fabrykę Abstrakcyjną. W rzeczywistym przypadku, wszystkie klasy/interfejsy będą oddzielnymi plikami, a same klasy fabryk jak i produktów, będą o wiele bardziej rozbudowane.
Podsumowanie
Niewątpliwie Fabryka Abstrakcyjna to ciekawy wzorzec projektowy, dający Tobie wiele możliwości wykorzystania i zabawy abstrakcją. Pozwala na zachowanie spójności między produktami – wszystkie pochodzą z jednej – wybranej na początku – fabryki. Dodatkowym atutem jest możliwość modyfikacji produktów, bez konieczności znania ich klas konkretnych.
Ważne abyś samemu zastanowił się i przemyślał, czy Abstract Factory to wzorzec projektowy który pasuje do Twojego problemu, czy może inny Wzorzec Projektowy byłby lepszy, a może prosty kod będzie wystarczający? Znajomość wzorców z pewnością pomoże Tobie w tych przemyśleniach.
Zainteresował Cię materiał? Zapraszam do listy mailowej, by być na bieżąco z kolejnymi wpisami.
[…] Przypomina Fabrykę Abstrakcyjną, też służy do tworzenia obiektów złożonych. Z tą różnicą, że Abstract Factory udostępnia produkt natychmiast, a Builder tworzy go krok po kroku i zwraca dopiero w ostatnim kroku. […]