Jaka jest różnica między wzorem projektowym Builder a wzorem fabrycznym?
Który jest bardziej korzystny i dlaczego?
Jak mogę przedstawić moje odkrycia jako wykres, jeśli chcę przetestować i porównać / porównać te wzorce?
Jaka jest różnica między wzorem projektowym Builder a wzorem fabrycznym?
Który jest bardziej korzystny i dlaczego?
Jak mogę przedstawić moje odkrycia jako wykres, jeśli chcę przetestować i porównać / porównać te wzorce?
Odpowiedzi:
W przypadku wzorców projektowych zwykle nie ma „bardziej korzystnego” rozwiązania, które działałoby we wszystkich przypadkach. To zależy od tego, co musisz wdrożyć.
Z Wikipedii:
Wpis w Wikipedii dotyczący wzorca projektowania fabryki: http://en.wikipedia.org/wiki/Factory_method_pattern
Wpis w Wikipedii dotyczący wzorca projektowania konstruktora: http://en.wikipedia.org/wiki/Builder_pattern
źródło
Fabryka to po prostu funkcja otacza konstruktora (być może jedna z innej klasy). Kluczowa różnica polega na tym, że wzorzec metody fabrycznej wymaga zbudowania całego obiektu w jednym wywołaniu metody, a wszystkie parametry przekazane są w jednym wierszu. Ostateczny obiekt zostanie zwrócony.
Z drugiej strony wzorzec konstruktora jest w istocie obiektem opakowującym wszystkie możliwe parametry, które można przekazać do wywołania konstruktora. Pozwala to na użycie metod ustawiających do powolnego budowania listy parametrów. Jedną dodatkową metodą klasy budowniczej jest metoda build (), która po prostu przekazuje obiekt konstruktora do pożądanego konstruktora i zwraca wynik.
W językach statycznych, takich jak Java, staje się to ważniejsze, gdy masz więcej niż garść (potencjalnie opcjonalnych) parametrów, ponieważ pozwala to uniknąć konieczności posiadania konstruktorów teleskopowych dla wszystkich możliwych kombinacji parametrów. Konstruktor umożliwia także stosowanie metod ustawiających do definiowania pól tylko do odczytu lub pól prywatnych, których nie można bezpośrednio modyfikować po wywołaniu konstruktora.
Podstawowy przykład fabryki
Przykład podstawowego konstruktora
Warto porównać próbki kodu z tych dwóch stron Wikipedii:
http://en.wikipedia.org/wiki/Factory_method_pattern
http://en.wikipedia.org/wiki/Builder_pattern
źródło
Wzorzec fabryczny można prawie postrzegać jako uproszczoną wersję wzorca budowniczego.
W fabryce wzór, fabryka jest odpowiedzialny za tworzenie różnych podtypów obiektu w zależności od potrzeb.
Użytkownik metody fabrycznej nie musi znać dokładnego podtypu tego obiektu. Przykład metody fabrycznej
createCar
może zwrócić obiektFord
lubHonda
obiekt wpisany na maszynie.We wzorze konstruktora różne podtypy są również tworzone za pomocą metody konstruktora, ale skład obiektów może się różnić w obrębie tej samej podklasy.
Aby kontynuować przykład samochodu, możesz mieć
createCar
metodę konstruktora, która tworzyHonda
obiekt z motywem czterocylindrowym lubHonda
obiekt z motywem 6 cylindrów. Wzorzec konstruktora pozwala na tę drobną ziarnistość.Diagramy zarówno wzoru konstruktora, jak i wzorca metody fabrycznej są dostępne na Wikipedii.
źródło
Wzorzec projektu konstruktora opisuje obiekt, który wie, jak wykonać inny obiekt określonego typu w kilku etapach. Utrzymuje stan potrzebny dla elementu docelowego na każdym etapie pośrednim. Zastanów się, przez co przechodzi StringBuilder, aby utworzyć końcowy ciąg.
Fabryczny wzorzec projektowy opisuje obiekt, który umie tworzyć kilka różnych, ale powiązanych rodzajów obiektów w jednym kroku, przy czym określony typ jest wybierany na podstawie podanych parametrów. Pomyśl o systemie serializacji, w którym tworzysz swój serializator, który tworzy pożądany obiekt w jednym wywołaniu obciążenia.
źródło
Konstruowanie złożonego obiektu krok po kroku: wzorzec konstruktora
Prosty obiekt jest tworzony przy użyciu jednej metody: wzorca metody fabrycznej
Tworzenie obiektu za pomocą wielu metod fabrycznych: Abstrakcyjny wzór fabryczny
źródło
Wzorzec konstruktora i wzorzec fabryczny, oba wydają się bardzo podobne do gołych oczu, ponieważ oba tworzą obiekty dla Ciebie.
Ale musisz przyjrzeć się bliżej
Ten przykład z życia sprawi, że różnica między nimi będzie bardziej wyraźna.
Załóżmy, że poszedłeś do restauracji typu fast food i zamówiłeś jedzenie .
1) Jakie jedzenie?
Pizza
2) Jakie polewy?
Papryka, pomidor, kurczak z grilla, bez sosny
Tak więc różne rodzaje żywności są wytwarzane według wzoru Factory, ale różne warianty (smaki) określonego jedzenia są tworzone według wzoru Builder.
Pizza, Burger, Makaron
Tylko ser, ser + pomidor + papryka, ser + pomidor itp.
Próbka kodu
Przykładową implementację kodu obu wzorców można zobaczyć tutaj
Wzorzec fabryczny wzorca budowniczego
źródło
Oba są wzorami kreacyjnymi, aby stworzyć Obiekt.
1) Wzorzec fabryczny - Załóżmy, że masz jedną superklasę i N liczbę podklas. Obiekt tworzony zależy od tego, który parametr / wartość jest przekazywana.
2) Wzorzec konstruktora - aby utworzyć złożony obiekt.
źródło
Najpierw kilka ogólnych rzeczy, które należy podążać za moją argumentacją:
Głównym wyzwaniem przy projektowaniu dużych systemów oprogramowania jest to, że muszą być elastyczne i nieskomplikowane do zmiany. Z tego powodu istnieją pewne wskaźniki, takie jak sprzężenie i spójność. Aby uzyskać systemy, które można łatwo zmienić lub rozszerzyć funkcjonalnie, bez konieczności przeprojektowywania całego systemu od zera, możesz przestrzegać zasad projektowania (takich jak SOLID itp.). Po jakimś czasie jakiś programista uznał, że jeśli przestrzegają tych zasad, istnieje kilka podobnych rozwiązań, które działały dobrze w przypadku podobnych problemów. Te standardowe rozwiązania okazały się wzorami projektowymi.
Wzorce projektowe mają więc wspierać przestrzeganie ogólnych zasad projektowania w celu uzyskania luźno sprzężonych systemów o wysokiej spójności.
Odpowiedź na pytanie:
Pytając o różnicę między dwoma wzorami, musisz zadać sobie pytanie, jaki wzór sprawia, że twój system jest bardziej elastyczny. Każdy wzorzec ma swój własny cel organizowania zależności między klasami w systemie.
Abstrakcyjny wzorzec fabryczny: GoF: „Zapewnij interfejs do tworzenia rodzin powiązanych lub zależnych obiektów bez określania ich konkretnych klas”.
Co to znaczy: Zapewniając taki interfejs, wywołanie konstruktora każdego z produktów rodziny jest zawarte w klasie fabrycznej. Ponieważ jest to jedyne miejsce w całym systemie, w którym nazywani są te konstruktory, możesz zmienić swój system, wdrażając nową klasę fabryczną. Jeśli wymienisz reprezentację fabryki za pośrednictwem innej, możesz wymienić cały zestaw produktów bez dotykania większości kodu.
Wzorzec konstruktora: GoF: „Oddziel konstrukcję złożonego obiektu od jego reprezentacji, aby ten sam proces budowy mógł tworzyć różne reprezentacje”.
Co to znaczy: obudowujesz proces budowy w innej klasie, zwanej reżyserem (GoF). Ten dyrektor zawiera algorytm tworzenia nowych instancji produktu (np. Komponuje złożony produkt z innych części). Do stworzenia integralnych części całego produktu reżyser używa konstruktora. Wymieniając konstruktor w reżyserze, możesz użyć tego samego algorytmu do stworzenia produktu, ale zmienić reprezentacje pojedynczych części (a więc i reprezentację produktu). Aby rozszerzyć lub zmodyfikować system w reprezentacji produktu, wystarczy zaimplementować nową klasę konstruktora.
W skrócie: Celem Abstrakcyjnego Wzorca Fabryki jest wymiana zestawu produktów, które są przeznaczone do wspólnego użytku. Wzorzec konstruktora ma na celu obudowanie abstrakcyjnego algorytmu tworzenia produktu w celu ponownego wykorzystania go do różnych reprezentacji produktu.
Moim zdaniem nie można powiedzieć, że Abstrakcyjny Wzór Fabryki jest starszym bratem Wzorca Budowniczego. TAK, oba są wzorami kreacyjnymi, ale ich główna intencja jest zupełnie inna.
źródło
Jedną uderzającą różnicą między Builderem a fabryką, którą mogłem zauważyć, była następująca
załóżmy, że mamy samochód
W powyższym interfejsie możemy uzyskać samochód w następujący sposób:
ale co jeśli zdarzy się jakiś wyjątek podczas tworzenia miejsc ??? W OGÓLE NIE MASZ OBIEKTU // ALE
załóżmy, że masz implementację taką jak poniżej
Teraz możesz tworzyć w ten sposób
Tutaj, w drugim przypadku, nawet jeśli jedna operacja się nie powiedzie, nadal dostaniesz samochód.
Być może później samochód nie będzie działał idealnie, ale będziesz miał obiekt.
Ponieważ metoda fabryczna daje samochód w jednym wywołaniu, podczas gdy Konstruktor buduje jeden po drugim.
Chociaż zależy to od potrzeb rycerza, który wybrać.
źródło
Konstruktor teleskopowy
Analogia:
Kurtuazja
źródło
Builder i Abstract Factory mają różne przeznaczenie. W zależności od właściwego zastosowania należy wybrać odpowiedni wzór.
Istotne cechy Buildera :
Istotne cechy fabryczne (prosta fabryka):
Często projekty zaczynają się od metody fabrycznej (mniej skomplikowane, bardziej konfigurowalne, podklasy rozprzestrzeniają się) i ewoluują w kierunku fabryki abstrakcyjnej , prototypu lub konstruktora (bardziej elastyczne, bardziej złożone)
Zobacz powiązane posty:
Utrzymywanie konstruktora w osobnej klasie (płynny interfejs)
Wzory projektowe: Fabryka kontra metoda fabryczna kontra fabryka abstrakcyjna
Więcej informacji można znaleźć w poniższych artykułach:
zaopatrzenie
dziennikaldev
źródło
Fabryka : Służy do tworzenia instancji obiektu, w której zależności obiektu są całkowicie utrzymywane przez fabrykę. W przypadku abstrakcyjnego wzorca fabryki często istnieje wiele konkretnych implementacji tej samej abstrakcyjnej fabryki. Właściwa implementacja fabryki jest wprowadzana poprzez wstrzykiwanie zależności.
Konstruktor : służy do budowania niezmiennych obiektów, gdy zależności obiektu, który ma zostać utworzony, są częściowo znane z góry, a częściowo dostarczane przez klienta konstruktora.
źródło
Wzory abstrakcyjne Fabryki i Konstruktora są wzorami Kreacyjnymi, ale mają różne intencje.
Abstrakcyjny wzór fabryczny podkreśla tworzenie obiektów dla rodzin powiązanych obiektów, w których:
Wzorzec konstruktora koncentruje się na konstruowaniu złożonego obiektu krok po kroku. Oddziela reprezentację od procesu konstruowania złożonego obiektu, dzięki czemu ten sam proces budowy można zastosować do różnych reprezentacji.
źródło
Złożona konstrukcja ma miejsce, gdy obiekt, który ma zostać zbudowany, składa się z różnych innych obiektów reprezentowanych przez abstrakcje.
Rozważ menu w McDonald's. Menu zawiera napój, danie główne i boczne. W zależności od tego, którzy potomkowie poszczególnych abstrakcji są skomponowani razem, utworzone menu ma inną reprezentację.
Tam mamy dwa wystąpienia menu z różnymi reprezentacjami. Z kolei proces budowy pozostaje taki sam. Tworzysz menu z drinkiem, daniem głównym i bocznym.
Używając wzorca konstruktora, oddzielasz algorytm tworzenia złożonego obiektu od różnych komponentów użytych do jego utworzenia.
Pod względem wzorca konstruktora algorytm jest zamknięty w dyrektorze, natomiast konstruktory służą do tworzenia integralnych części. Różnicowanie używanego konstruktora w algorytmie reżysera powoduje inną reprezentację, ponieważ inne części składają się w menu. Sposób tworzenia menu pozostaje taki sam.
źródło
Główna różnica między nimi polega na tym, że wzorzec Konstruktora opisuje przede wszystkim tworzenie złożonych obiektów krok po kroku. We wzorze fabryki abstrakcyjnej nacisk kładziony jest na rodziny przedmiotów-produktów . Konstruktor zwraca produkt w ostatnim kroku . Podczas gdy we wzorze Abstract Factory produkt jest dostępny natychmiast .
Przykład: Powiedzmy, że tworzymy Labirynt
1. Fabryka abstrakcyjna:
2. Konstruktor:
źródło
Uważam, że użycie i różnica między wzorcami Factory i Builder można łatwiej zrozumieć / wyjaśnić w pewnym okresie czasu, gdy pracujesz na tej samej podstawie kodu i zmieniających się wymaganiach.
Z mojego doświadczenia wynika, że zwykle zaczynasz od wzorca fabrycznego zawierającego kilka statycznych metod twórczych, aby przede wszystkim ukryć stosunkowo złożoną logikę inicjalizacji. W miarę jak twoja hierarchia obiektów staje się bardziej złożona (lub gdy dodajesz więcej typów, parametrów), prawdopodobnie twoje metody są zapełniane większą liczbą parametrów i nie wspominając o tym, że będziesz musiał ponownie skompilować moduł Factory. Wszystkie te rzeczy zwiększają złożoność metod twórców, zmniejszają czytelność i sprawiają, że moduł tworzenia jest bardziej kruchy.
Ten punkt prawdopodobnie będzie punktem przejścia / rozszerzenia. W ten sposób utworzysz moduł otoki wokół parametrów konstrukcyjnych, a następnie będziesz mógł reprezentować nowe (podobne) obiekty, dodając więcej abstrakcji (być może) i implementacji bez dotykania faktycznej logiki tworzenia. Masz więc „mniej” złożoną logikę.
Szczerze mówiąc, różnica w czymś w rodzaju „posiadania obiektu utworzonego w jednym lub wielu krokach jest różnicą”, ponieważ jedyny czynnik różnorodności nie był dla mnie wystarczający, aby je rozróżnić, ponieważ mogłem używać obu sposobów w prawie wszystkich przypadkach, z którymi miałem do czynienia teraz bez żadnych korzyści. Więc to w końcu o tym pomyślałem.
źródło
Główną zaletą wzorca konstruktora w porównaniu do wzorca fabrycznego jest to, że jeśli chcesz stworzyć jakiś standardowy obiekt z wieloma możliwymi dostosowaniami, ale zwykle kończy się to dostosowywaniem tylko kilku.
Na przykład, jeśli chcesz napisać klienta HTTP - skonfigurujesz pewne domyślne parametry, takie jak domyślny limit czasu zapisu / odczytu, protokoły, pamięć podręczna, DNS, przechwytywacze itp.
Większość użytkowników Twojego klienta będzie po prostu używać tych domyślnych parametrów, podczas gdy niektórzy inni użytkownicy mogą chcieć dostosować niektóre z pozostałych parametrów. W niektórych przypadkach wystarczy zmienić limity czasu i wykorzystać resztę bez zmian, aw innych przypadkach może być konieczne dostosowanie na przykład pamięci podręcznej.
Oto możliwe sposoby tworzenia instancji klienta (wzięte z OkHttpClient):
Jeśli użyjesz do tego wzoru fabrycznego, skończysz pisać wiele metod ze wszystkimi możliwymi kombinacjami parametrów tworzenia. Dzięki konstruktorowi określasz tylko te, na których Ci zależy, i pozwalasz konstruktorowi zbudować go, aby zajął się wszystkimi innymi parametrami.
źródło
Wzorzec budowy kładzie nacisk na złożoność tworzenia obiektu (rozwiązany przez „kroki”)
Abstrakcyjny wzór kładzie nacisk na „tylko” na „abstrakcję” (wielu, ale powiązanych) obiektów.
źródło
Różnica jest wyraźna We wzorcu konstruktora konstruktor utworzy dla Ciebie określony typ obiektu. Musisz powiedzieć, co budowniczy ma zbudować. We wzorcu fabrycznym, używając klasy abstrakcyjnej, bezpośrednio budujesz konkretny obiekt.
Tutaj klasa konstruktora działa jako mediator między klasą główną a klasami określonego typu. Więcej abstrakcji.
źródło
Oba są bardzo podobne, ale jeśli masz dużą liczbę parametrów do tworzenia obiektów, a niektóre z nich są opcjonalne z pewnymi wartościami domyślnymi, wybierz wzorzec Konstruktora.
źródło
moim zdaniem
Konstruktor jest bardziej złożoną fabryką.
Ale w programie Builder można tworzyć instancje obiektów za pomocą innych fabryk , które są wymagane do zbudowania ostatecznego i poprawnego obiektu.
Mówiąc o ewolucji „Wzorów Kreacyjnych” według złożoności, możesz o tym pomyśleć w ten sposób:
źródło
Oba wzorce mają tę samą potrzebę: ukryj przed kodem klienta logikę budowy złożonego obiektu. Ale co sprawia, że „złożony” (a czasem komplikuje) obiekt? Głównie wynika to z zależności, a raczej ze stanu obiektu złożonego z bardziej częściowych stanów. Konstruktor może wstrzykiwać zależności, aby ustawić początkowy stan obiektu, ale obiekt może wymagać ich wielu, niektóre będą w domyślnym stanie początkowym (tylko dlatego, że powinniśmy się dowiedzieć, że ustawienie domyślnej zależności na wartość null nie jest najczystszym sposobem ) i niektóre inne ustawione na stan sterowany przez jakiś warunek. Ponadto istnieją właściwości obiektów, które są pewnego rodzaju „nieświadomymi zależnościami”, ale mogą również przyjmować stany opcjonalne.
istnieją dwa dobrze znane sposoby zdominowania tej złożoności:
Kompozycja / agregacja: Zbuduj obiekt, zbuduj zależne obiekty, a następnie połącz ze sobą. Tutaj konstruktor może uczynić proces przejrzystym i elastycznym, który określa reguły, które prowadzą do budowy komponentu.
Polimorfizm: reguły budowy są deklarowane bezpośrednio w definicji podtypu, więc masz zestaw reguł dla każdego podtypu, a niektóre warunki decydują, który z tych zestawów reguł ma zastosowanie do budowy obiektu. Fabryka idealnie pasuje do tego scenariusza.
Nic nie stoi na przeszkodzie, aby połączyć te dwa podejścia. Rodzina produktów może tworzyć abstrakcyjne obiekty za pomocą konstruktora, konstruktor może wykorzystywać fabryki do określania, który obiekt komponentu tworzy się.
źródło
Moim zdaniem wzorzec Konstruktora jest używany, gdy chcesz utworzyć obiekt z szeregu innych obiektów, a tworzenie części musi być niezależne od obiektu, który chcesz utworzyć. Pomaga ukryć tworzenie części przed klientem, aby konstruktor i klient byli niezależni. Służy do tworzenia złożonych obiektów (obiektów, które mogą składać się ze skomplikowanych właściwości)
Podczas gdy wzorzec fabryczny określa, że chcesz tworzyć obiekty ze wspólnej rodziny i chcesz, aby była od razu cerowana. Służy do prostszych obiektów.
źródło
Od: http://www.oodesign.com/builder-pattern.html
źródło
Wzorzec fabryczny tworzy konkretną implementację klasy w czasie wykonywania, tj. Jej głównym celem jest użycie polimorfizmu, aby umożliwić podklasom decydowanie, która klasa ma zostać utworzona. Oznacza to, że w czasie kompilacji nie znamy dokładnej klasy, która zostanie utworzona, podczas gdy wzorzec Konstruktora zajmuje się głównie rozwiązywaniem problemu teleskopowego konstruowania antipatternu, który powstaje z powodu dużej liczby opcjonalnych pól klasy. We wzorcu konstruktora nie ma pojęcia polimorfizmu, ponieważ wiemy, jaki obiekt próbujemy zbudować w czasie kompilacji.
Jedynym wspólnym tematem tych dwóch wzorów jest ukrywanie konstruktorów i tworzenie obiektów za metodami fabrycznymi oraz metoda budowania w celu poprawy konstrukcji obiektów.
źródło
Wzorzec fabryczny pozwala od razu utworzyć obiekt, a wzorzec konstruktora pozwala przerwać proces tworzenia obiektu. W ten sposób możesz dodać inną funkcjonalność podczas tworzenia obiektu.
źródło