Wiem, że istnieje wiele postów na temat różnic między tymi dwoma wzorami, ale jest kilka rzeczy, których nie mogę znaleźć.
Z tego, co czytałem, widzę, że wzorzec metody fabrycznej pozwala ci zdefiniować, jak stworzyć pojedynczy konkretny produkt, ale ukrywając implementację przed klientem, ponieważ zobaczą ogólny produkt. Moje pierwsze pytanie dotyczy fabryki abstrakcyjnej. Czy jego rola polega na umożliwieniu tworzenia rodzin konkretnych obiektów (które mogą zależeć od konkretnej fabryki, której używasz), a nie tylko jednego konkretnego obiektu? Czy fabryka abstrakcyjna zwraca tylko jeden bardzo duży obiekt lub wiele obiektów w zależności od wywoływanych metod?
Moje ostatnie dwa pytania dotyczą jednego cytatu, którego nie rozumiem w pełni w wielu miejscach:
Jedna różnica między nimi polega na tym, że we wzorcu fabryki abstrakcyjnej klasa przenosi odpowiedzialność tworzenia instancji obiektu na inny obiekt poprzez kompozycję, podczas gdy wzorzec metody fabryki używa dziedziczenia i korzysta z podklasy do obsługi żądanej instancji obiektu.
Rozumiem, że wzorzec metody fabrycznej ma interfejs Creatora, który sprawi, że ConcreteCreator będzie odpowiedzialny za określenie, który konkretny produkt betonowy utworzyć. Czy to oznacza używanie dziedziczenia do obsługi instancji obiektów?
W odniesieniu do tego cytatu, w jaki sposób wzorzec Fabryki Abstrakcyjnej przenosi odpowiedzialność tworzenia instancji obiektu na inny obiekt poprzez kompozycję? Co to znaczy? Wygląda na to, że wzorzec Fabryki Abstrakcyjnej również korzysta z dziedziczenia, aby wykonać proces budowy również w moich oczach, ale znowu uczę się o tych wzorach.
Każda pomoc, szczególnie w przypadku ostatniego pytania, byłaby bardzo mile widziana.
Odpowiedzi:
Różnica między tymi dwoma
Główna różnica między „metodą fabryczną” a „fabryką abstrakcyjną” polega na tym, że metoda fabryczna jest pojedynczą metodą, a fabryka abstrakcyjna jest obiektem. Myślę, że wielu ludzi myli te dwa terminy i zaczęło ich używać zamiennie. Pamiętam, że ciężko mi było znaleźć dokładnie różnicę, kiedy się ich nauczyłem.
Ponieważ metoda fabryczna jest tylko metodą, można ją zastąpić w podklasie, stąd druga połowa cytatu:
Cytat zakłada, że obiekt wywołuje tutaj własną metodę fabryczną. Dlatego jedyną rzeczą, która mogłaby zmienić wartość zwracaną, byłaby podklasa.
Fabryka abstrakcyjna to obiekt, który ma wiele metod fabrycznych. Patrząc na pierwszą połowę wyceny:
Mówią, że istnieje obiekt A, który chce stworzyć obiekt Foo. Zamiast tworzyć sam obiekt Foo (np. Metodą fabryczną), otrzyma inny obiekt (fabryka abstrakcyjna), aby utworzyć obiekt Foo.
Przykłady kodu
Aby pokazać różnicę, stosowana jest metoda fabryczna:
A oto używana abstrakcyjna fabryka:
źródło
SpecialFoo
aby było bardziej jasne.Fabryka abstrakcyjna tworzy klasę podstawową z metodami abstrakcyjnymi definiującymi metody dla obiektów, które powinny zostać utworzone. Każda klasa fabryki, która wywodzi klasę podstawową, może stworzyć własną implementację każdego typu obiektu.
Metoda fabryczna to po prostu prosta metoda służąca do tworzenia obiektów w klasie. Zwykle jest dodawany w zagregowanym katalogu głównym (
Order
klasa ma metodę o nazwieCreateOrderLine
)Fabryka abstrakcyjna
W poniższym przykładzie projektujemy interfejs, dzięki czemu możemy oddzielić tworzenie kolejek od systemu przesyłania komunikatów, a zatem możemy tworzyć implementacje dla różnych systemów kolejek bez konieczności zmiany podstawy kodu.
Metoda fabryczna
Problem w serwerach HTTP polega na tym, że zawsze potrzebujemy odpowiedzi na każde żądanie.
Bez metody fabrycznej użytkownicy serwera HTTP (tj. Programiści) byliby zmuszeni do korzystania z klas specyficznych dla implementacji, które podważają przeznaczenie
IHttpRequest
interfejsu.Dlatego wprowadzamy metodę fabryki, aby tworzenie klasy odpowiedzi również zostało oderwane.
Podsumowanie
Różnica polega na tym, że przeznaczeniem klasy zawierającej metodę fabryczną nie jest tworzenie obiektów , podczas gdy abstrakcyjna fabryka powinna być używana tylko do tworzenia obiektów.
Należy zachować ostrożność podczas korzystania z metod fabrycznych, ponieważ łatwo jest złamać LSP ( zasada podstawienia Liskowa ) podczas tworzenia obiektów.
źródło
Button()
„rodzinę powiązanych produktów”. Na przykład kanoniczny przykład GoF tworzyScrollBar()
iWindow()
. Zaletą jest to, że Fabryka abstrakcyjna może egzekwować wspólny temat dla wielu swoich produktów.Różnice między wzorcami projektowymi AbstractFactory i Factory są następujące:
Wdrożenie wzorca metody fabrycznej:
Wdrożenie abstrakcyjnego wzoru fabrycznego:
źródło
Główną różnicą między Fabryką abstrakcyjną a Metodą fabryczną jest to, że Fabryka abstrakcyjna jest implementowana przez Composition ; ale metoda fabryczna jest wdrażana przez dziedziczenie .
Tak, czytasz to poprawnie: główną różnicą między tymi dwoma wzorami jest stara debata nad kompozycją a dziedziczeniem .
Diagramy UML można znaleźć w książce (GoF). Chcę podać przykłady kodu, ponieważ myślę, że połączenie przykładów z dwóch pierwszych odpowiedzi w tym wątku da lepszą demonstrację niż każda z odpowiedzi osobno. Dodatkowo użyłem terminologii z książki w nazwach klas i metod.
Fabryka abstrakcyjna
Metoda fabryczna
ConcreteCreator
to, że klient. Innymi słowy, klient jest podklasą, której rodzic definiujefactoryMethod()
. Dlatego mówimy, że Metoda Fabryczna jest wdrażana przez Dziedziczenie.Creator
klasa (macierzysta) wywołuje swoją własnąfactoryMethod()
. Jeśli usuniemyanOperation()
z klasy nadrzędnej, pozostawiając za sobą tylko jedną metodę, nie będzie to już wzorzec metody fabrycznej. Innymi słowy, metoda fabryczna nie może zostać zaimplementowana przy użyciu mniej niż dwóch metod w klasie nadrzędnej; i jedno musi przywołać drugie.Misc. I różne wzory fabryczne
Należy pamiętać, że chociaż GoF definiują dwa różne wzorce fabryczne, nie są to jedyne istniejące wzorce fabryczne. Niekoniecznie są to najczęściej używane wzory fabryczne. Słynny trzeci przykład to Static Factory Pattern Josha Blocha z Effective Java. Książka Head First Design Patterns zawiera jeszcze jeden wzór, który nazywają Simple Factory.
Nie wpadnij w pułapkę zakładając, że każdy wzór Fabryki musi pasować do jednego z GoF.
źródło
factoryMethod()
zawsze powinna byćprotected
metoda we wzorcu „Metoda fabryczna”? (Myślę, że tak)public
metody fabryczne, a metoda nie musi nawet byćabstract
; ale krytycznym punktem jest to, że sposób ten jest przeznaczony do dziedziczenia, tak że nie może (na przykład) jest albostatic
czyfinal
. Stworzyłem metodęprotected
iabstract
tutaj, aby podkreślić (wymaganą) rozszerzalność.Abstract Factory to interfejs do tworzenia powiązanych produktów, ale Factory Method to tylko jedna metoda. Fabrykę abstrakcyjną można wdrożyć wieloma metodami fabrycznymi.
źródło
Rozważ ten przykład dla łatwego zrozumienia.
Co zapewniają firmy telekomunikacyjne? Na przykład internet szerokopasmowy, linia telefoniczna i telefon komórkowy. Zostaniesz poproszony o stworzenie aplikacji, aby oferować swoje produkty klientom.
Ogólnie rzecz biorąc, to co tutaj robisz, to tworzenie produktów, tj. Łącza szerokopasmowego, linii telefonicznej i urządzeń mobilnych, za pomocą metody fabrycznej której wiesz, jakie masz właściwości tych produktów i jest to dość proste.
Teraz firma chce zaoferować swojemu klientowi pakiet swoich produktów, tj. Łączność szerokopasmową, linię telefoniczną i telefon komórkowy, i oto gra Abstract Factory .
Innymi słowy, Abstract Factory to skład innych fabryk, które są odpowiedzialne za tworzenie własnych produktów, a Abstract Factory wie, jak umieścić te produkty w sposób bardziej znaczący w odniesieniu do własnych obowiązków.
W tym przypadku
BundleFactory
jest Abstract FactoryBroadbandFactory
,PhonelineFactory
iMobileFactory
sąFactory
. Aby jeszcze bardziej uprościć, fabryki te będą miały metodę fabryczną inicjowania poszczególnych produktów.Zobacz przykładowy kod poniżej:
Mam nadzieję że to pomoże.
źródło
static
metod we wzorcach fabrycznych GoF. To jest źle.Przykład z prawdziwego życia. (Łatwe do zapamiętania)
Fabryka
Wyobraź sobie, że budujesz dom i zbliżasz się do cieśli w poszukiwaniu drzwi. Dajesz pomiar drzwi i twoich wymagań, a on zbuduje dla ciebie drzwi. W tym przypadku stolarz jest fabryką drzwi. Twoje dane techniczne są danymi wejściowymi dla fabryki, a drzwi są wyjściem lub produktem z fabryki.
Fabryka abstrakcyjna
Rozważmy teraz ten sam przykład drzwi. Możesz iść do cieśli lub do sklepu z plastikowymi drzwiami lub sklepu z PCV. Wszystkie są fabrykami drzwi. Na podstawie sytuacji decydujesz, do jakiego rodzaju fabryki chcesz się udać. To jest jak Fabryka Abstrakcyjna.
Wyjaśniłem tutaj zarówno wzorzec metody fabrycznej, jak i abstrakcyjny wzorzec fabryczny, zaczynając od nieużywania ich wyjaśniania problemów, a następnie rozwiązywania problemów za pomocą powyższych wzorców https://github.com/vikramnagineni/Design-Patterns/tree/master
źródło
Wyjaśnijmy jasno, że przez większość czasu w kodzie produkcyjnym używamy abstrakcyjnego wzorca fabrycznego, ponieważ klasa A jest programowana za pomocą interfejsu B. A A musi tworzyć instancje B. Tak więc A musi mieć obiekt fabryczny do tworzenia instancji B Tak więc A nie jest zależne od żadnego konkretnego wystąpienia B. Mam nadzieję, że to pomoże.
źródło
Zrozum różnice w motywacjach:
Załóżmy, że budujesz narzędzie, w którym masz obiekty i konkretną implementację wzajemnych powiązań obiektów. Ponieważ przewidujesz różnice w obiektach, stworzyłeś pośredniość, przypisując odpowiedzialność za tworzenie wariantów obiektów do innego obiektu ( nazywamy to fabryką abstrakcyjną ). Ta abstrakcja ma dużą zaletę, ponieważ przewiduje się przyszłe rozszerzenia wymagające wariantów tych obiektów.
Inną dość intrygującą motywacją w tej linii myśli jest przypadek, w którym każdy przedmiot z całej grupy będzie miał odpowiedni wariant. W zależności od pewnych warunków, zastosowany zostanie jeden z wariantów, i za każdym razem wszystkie obiekty muszą być tego samego wariantu. Może to być nieco sprzeczne z intuicją, ponieważ często wydaje nam się, że - o ile warianty obiektu są zgodne ze wspólnym jednolitym kontraktem ( interfejs w szerszym znaczeniu ), konkretny kod implementacyjny nigdy nie powinien ulec awarii. Intrygującym faktem jest to, że nie zawsze jest to prawdą, szczególnie gdy oczekiwanego zachowania nie można modelować w umowie programowej.
Prosty ( zapożyczenie pomysłu z GoF ) jest każda aplikacja GUI, która mówi, że wirtualny monitor emuluje wygląd MS, Mac lub Fedory. Tutaj, na przykład, gdy wszystkie obiekty widżetów, takie jak okno, przycisk itp. Mają wariant MS, z wyjątkiem paska przewijania, który pochodzi z wariantu MAC, przeznaczenie narzędzia nie powiedzie się.
Te powyższe przypadki stanowią podstawową potrzebę abstrakcyjnego wzorca fabrycznego .
Z drugiej strony, wyobraź sobie, że piszesz platformę, aby wiele osób mogło zbudować różne narzędzia ( takie jak powyższe przykłady ) za pomocą tej platformy. Zgodnie z ideą frameworku nie musisz tego robić, chociaż nie możesz użyć konkretnych obiektów w swojej logice. Raczej stawiasz kontrakty na wysokim poziomie między różnymi obiektami i sposób ich interakcji. Podczas gdy Ty ( jako programista frameworka ) pozostajesz na bardzo abstrakcyjnym poziomie, każdy budowniczy narzędzia jest zmuszony podążać za twoimi konstrukcjami frameworka. Jednak oni ( twórcy narzędzi ) mają swobodę decydowania, który obiekt ma zostać zbudowany i w jaki sposób wszystkie obiekty, które utworzą, będą oddziaływać. W przeciwieństwie do poprzedniego przypadku ( abstrakcyjnego wzoru fabrycznego ), ty ( jako twórca frameworka)) w tym przypadku nie trzeba pracować z konkretnymi obiektami; i raczej może pozostać na poziomie umownym przedmiotów. Co więcej, w przeciwieństwie do drugiej części poprzednich motywacji, ty lub twórcy narzędzi nigdy nie masz sytuacji mieszania przedmiotów z wariantów. Tutaj, podczas gdy kod frameworka pozostaje na poziomie kontraktu, każdy twórca narzędzi jest ograniczony ( ze względu na naturę samej sprawy ) do używania własnych obiektów. Tworzenie obiektów w tym przypadku jest delegowane do każdego implementatora, a dostawcy ram zapewniają tylko jednolite metody tworzenia i zwracania obiektów. Takie metody są nieuniknione dla programisty frameworka, aby kontynuowały kod i mają specjalną nazwę o nazwie Metoda fabryczna ( Wzorzec metody fabrycznej dla wzorca bazowego ).
Kilka uwag:
Przykładowy kod:
źródło
Tak. Intencją fabryki abstrakcyjnej jest:
Idealnie powinien zwrócić jeden obiekt na metodę, którą wywołuje klient.
Tak. Metoda fabryczna wykorzystuje dziedziczenie.
AbstractFactory definiuje FactoryMethod, a ConcreteFactory odpowiada za budowę produktu betonowego. Wystarczy postępować zgodnie z przykładem kodu w tym artykule .
Możesz znaleźć więcej szczegółów w powiązanych postach SE:
Jaka jest podstawowa różnica między fabrycznymi i abstrakcyjnymi wzorami fabrycznymi?
Wzory projektowe: Fabryka kontra metoda fabryczna kontra fabryka abstrakcyjna
źródło
Metoda fabryczna polega na dziedziczeniu: tworzenie obiektów jest delegowane do podklas, które implementują metodę fabryczną do tworzenia obiektów.
Fabryka abstrakcyjna opiera się na składzie obiektu: tworzenie obiektu jest realizowane metodami ujawnionymi w interfejsie fabryki.
Schemat wysokiego poziomu schematu fabrycznego i abstrakcyjnego,
Aby uzyskać więcej informacji na temat metody Factory, zapoznaj się z tym artykułem .
Aby uzyskać więcej informacji na temat metody fabryki abstrakcyjnej, patrz tym artykułem .
źródło
Aby było to bardzo proste z minimalnym interfejsem i skoncentruj się na „// 1”:
Oto ważne punkty: 1. Mechanizmy Factory i AbstractFactory muszą używać dziedziczenia (System.Object-> bajt, zmiennoprzecinkowy ...); więc jeśli masz dziedziczenie w programie, wówczas Fabryka (Fabryka Abstrakcyjna najprawdopodobniej tam nie byłaby) jest już tam według projektu 2. Twórca (MyFactory) wie o typie betonu, więc zwraca obiekt typu betonowego do obiektu wywołującego (Główny); W abstrakcyjnym typie zwrotu fabrycznego byłby interfejs.
Ważne punkty: 1. Wymaganie: Honda stworzy „Regular”, „Sport”, ale Hero stworzy „DarkHorse”, „Sports” i „Scooty”. 2. dlaczego dwa interfejsy? Jeden dla typu producenta (IVehicleFactory), a drugi dla fabryki produktu (IVehicle); innym sposobem na zrozumienie 2 interfejsów jest fabryka abstrakcyjna, polegająca na tworzeniu powiązanych obiektów 2. Chwytem jest powrót dzieci IVehicleFactory i IVehicle (zamiast betonu w fabryce); więc otrzymuję zmienną nadrzędną (IVehicle); następnie tworzę rzeczywisty typ betonu, wywołując CreateSingleVehicle, a następnie rzutując obiekt nadrzędny na rzeczywisty obiekt podrzędny. Co by się stało, gdybym to zrobił
RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");
; dostaniesz ApplicationException i dlatego potrzebujemy generycznej fabryki abstrakcyjnych, które wyjaśnię w razie potrzeby.źródło
Fabryka abstrakcyjna : fabryka fabryk; fabryka, która grupuje poszczególne, ale powiązane / zależne fabryki, bez określania ich konkretnych klas. Przykład fabryki abstrakcyjnej
Fabryka : Zapewnia sposób na przekazanie logiki tworzenia instancji klasom potomnym. Przykładowy wzór fabryczny
źródło
W każdej chwili wolałbym Abstract Factory od Factory Method. Z powyższego przykładu Toma Dallinga (świetne wyjaśnienie btw) widzimy, że Abstract Factory jest bardziej podatna na kompozycję, ponieważ wszystko, co musimy zrobić, to przekazać konstruktorowi inną Fabrykę (tutaj stosuje się wstrzykiwanie zależności konstruktorów). Ale metoda fabryczna wymaga od nas wprowadzenia nowej klasy (więcej rzeczy do zarządzania) i zastosowania podklas. Zawsze preferuj kompozycję niż dziedziczenie.
źródło
pozwól mi to precyzyjnie ująć. większość odpowiedzi już wyjaśniła, podając również schematy i przykłady. więc moja odpowiedź będzie tylko jedną linią. moje własne słowa: - „abstrakcyjny wzór fabryki dodaje warstwę abstrakcyjną w wielu implementacjach metod fabrycznych. oznacza, że abstrakcyjna fabryka zawiera lub składa jeden lub więcej wzorów metod fabrycznych ”
źródło
Wiele z powyższych odpowiedzi nie zapewnia porównania kodu między wzorcem Abstract Factory i Factory Method. Oto moja próba wyjaśnienia tego za pomocą Java. Mam nadzieję, że pomoże to komuś potrzebującemu prostego wyjaśnienia.
źródło