2009-12-22 13 views
22

Widziałem, jak to pytanie powstało tu i tam kilka razy, ale nigdy nie znalazłem i nie odpowiedziałem, że byłem szczęśliwy.Gdzie użyłbyś wzorca budowniczego zamiast abstrakcyjnej fabryki?

Z Wikipedii:

Builder koncentruje się na budowie złożonego obiektu krok po kroku. Abstract Factory kładzie nacisk na rodzinę obiektów produktowych (prostych lub złożonych). Builder zwraca produkt jako ostatni krok, ale jeśli chodzi o Abstract Factory, produkt zostaje natychmiast zwrócony.

Ale dla klienta to nie to samo? Dostaje pełny obiekt po jego zbudowaniu, więc dla niego nie ma żadnej dodatkowej funkcjonalności.

Jedyny sposób, w jaki widzę, to sposób lub organizowanie kodu konstruktora w krokach, aby wymusić strukturę dla implementacji budowniczych. Co jest miłe, ale nie jest to wielki krok od abstrakcyjnej fabryki.


Następny bit z Wikipedii jest dobre referencje, aby dostać się do mojego punktu:

Często projekty zaczynają się przy użyciu metody fabryki (mniej skomplikowane, bardziej konfigurowalny, podklasy rozmnażać) i ewoluować w kierunku Abstrakcja Fabryka, prototyp lub budowniczy (bardziej elastyczny, bardziej złożony), ponieważ projektant odkrywa, gdzie potrzebna jest większa elastyczność.

Jeśli tak, to jaka złożoność musiałaby zostać wprowadzona w systemie, w którym zmieniłbyś się z fabryki abstrakcyjnej na konstruktora?

Chodzi mi o to, że nie mogę znaleźć i podać przykładu, gdzie jest jasne, że abstrakcyjna fabryka nie wystarczy i zamiast tego potrzebny byłby Builder.

+1

+1 doskonałe pierwsze pytanie Lino! Powinieneś częściej wskakiwać :-)! – KLE

+0

Dzięki, KLE. Nadal przeszkadza mi, chociaż :). Chodzi mi o to, że jeśli budujesz złożone obiekty, a ty zabierasz dyrektora, przekazując odpowiedzialność za wywoływanie metod budowniczych klientom, to działa to dla mnie. Tylko wtedy budowniczy wydaje się idealnie pasować. Ale z reżyserem to nie wydaje się dużo ... –

+0

@Lino Precyzyjnie ** Builder nie ma dyrektora **, pozwala każdemu klientowi stworzyć złożony produkt ** zgodnie ze swoimi specyficznymi potrzebami **. Zazwyczaj żaden z dwóch klientów Buildera nie zbudowałby tego samego produktu. Jeśli ma to na celu stworzenie złożonego konstruktora w sposób hermetyzujący i wielokrotnego użytku (reżyser), to możesz mieć metodę hermetyzacji tego (i jest twoim "dyrektorem"). Wręcz przeciwnie, w przypadku ** AbstractFactory ** zazwyczaj potrzebujesz dyrektora wielokrotnego użytku, który ** tworzy produkty podobne ** (dostarczone z wdrożeniem w Fabryce). – KLE

Odpowiedz

13

The AbstractFactory jest przeznaczony dla rodziny powiązanych produktów. Builder jest dla jednego produktu.

Konstruktor służy do budowania złożonego produktu krok po kroku, podczas gdy AbstractFactory ma budować w sposób abstrakcyjny (czyli raz dla kilku wdrożeń) mniej złożony produkt.


Przykłady jaka jest różnica oznacza kodu wywołującego:

  • do kodu klienta przy użyciu AbstractFactory, każde wywołanie metody buduje jeden obiekt. Klient musi je złożyć razem:. Z drugiej strony budowniczy montowałby je wewnętrznie i dostarczał pełny wykres obiektów jako ostatni etap budynku.

  • Konstruktor umożliwia przesyłanie i sprawdzanie parametrów pojedynczo dla kodu klienta. Ale może on zbudować produkt końcowy w jednym kroku (na przykład wywołanie konstruktora, przekazanie wszystkich parametrów jednocześnie, nawet zaawansowanych, które zostały zbudowane samodzielnie). Tak więc produkt konstruktora może być niezmiennym obiektem (lub wykresem) (co jest bezcenne w środowisku wielowątkowym, ze względu na wydajność i pamięć).


AKTUALIZACJA w odpowiedzi na komentarz:

Lino> To wciąż mnie niepokoi, choć :). Chodzi mi o to, że jeśli budujesz złożone obiekty, a ty zabierasz dyrektora, przekazując odpowiedzialność za wywoływanie metod budowniczych klientom, to działa to dla mnie. Tylko wtedy budowniczy wydaje się idealnie pasować. Ale z reżyserem, doens't wydawać się dużo ...

Dokładnie Budowniczy ma reżysera, pozwala każdemu klientowi stworzyć kompleksowy produkt według niego jest specyficzne potrzeby. Klient jest reżyserem, ponieważ implementacja reżysera nie jest ponownie wykorzystywana.

Jeśli trzeba ponownie użyć kilka razy złożonego procesu budowlanego, a następnie można mieć metodę enkapsulacji to (i ta metoda jest twój „dyrektor”).

Wręcz przeciwnie, dla AbstractFactory, zazwyczaj trzeba wielokrotnego użytku dyrektora, że ​​tworzenie produktów zarówno (dostarczonych z realizacji fabryczne).

+0

Z pewnością jednym z plusów wzorca budowniczego jest możliwość ponownego wykorzystania reżysera. Jednym z moich ulubionych przykładów budowniczego jest SAX, gdzie parser wielokrotnego użytku (program budujący) może być używany z dostarczoną przez użytkownika obsługą treści (budowniczym) do budowania reprezentacji. Reżyser i budowniczy są niezależnie do wielokrotnego użytku. –

2

Builder jest użyteczny do konfiguracji. Abstract Factory jest przydatna, gdy nie chcesz, aby rozmówcy dbają o rzeczywistą implementację. Dwa różne cele.

Można w rzeczywistości wymieszać dwa wzory. Na przykład Java DocumentBuilderFactory jest klasyczną fabryką abstrakcyjną: jeśli czytasz dokumenty, zobaczysz proces, którego używa do wybrania implementacji. Jednak utworzone przez niego DocumentBuilder mogą być skonfigurowane później (chociaż nie są zgodne z prototypowym podejściem "konstruktora", ponieważ każda metoda konfiguracji zwraca obiekt, który jest konfigurowany).

1

Używam fabryki abstrakcyjnej, kiedy będę potrzebował zbudować wiele fabryk potomnych, aby stworzyć różne typy obiektów. Wszystkie te fabryki dzieci wdrażają lub rozszerzają fabrykę abstrakcyjną. Używam Buildera, gdy istnieje tylko jeden typ obiektu, który należy zbudować.

Nie jestem pewien, czy to jest poprawne użycie, ale tak właśnie widziałem, jak to zrobiłem i jak to zrobiłem w przeszłości.

4

Jeden dobry przykład, w którym chcesz budować, jeśli budujesz coś po kawałku w oparciu o argumenty wiersza poleceń. Na przykład, rozważmy konstruktora z metod, takich jak ...

setName() 
setType() 
setOption() 

Konstruktor może być również połączona z abstrakcyjnego fabryce, w której reżyser prosi fabrykę w konkretnym produkcie. Znów można to zrobić za pomocą wzoru fabrycznego, przekazując listę argumentów do fabryki, ale co, jeśli argumenty były zamiast tego wiadomościami pochodzącymi z serwera lub klienta.

Czasami estetyka jednego wzoru pasuje lepiej niż estetyka drugiego.

+0

"Znowu można to zrobić za pomocą wzoru fabrycznego, przekazując listę argumentów do fabryki, ale co, jeśli argumenty były zamiast wiadomości przychodzących z serwera lub klienta." Ale wtedy odpowiedzialność za wywoływanie metod kreacji na budowniczych (setName, setType ...) zostałaby przeniesiona na klientów, prawda? Aby to działało, odpowiednie atrybuty utworzonych klas musiałyby być opcjonalne lub stworzyć niespójny obiekt. Zaczynam myśleć, że tam właśnie buduje się światło: kiedy przenosisz odpowiedzialność na klienta, a atrybuty są opcjonalne –

+0

To nie brzmi poprawnie. Moje rozumienie wzorca Buildera polega na tym, że masz dyrektora (algorytmu konstrukcyjnego), który wykonuje wszystkie wywołania budowniczego (tworzy reprezentację obiektu) dla klienta. Klient może wybrać budowniczego lub użyć fabryki, aby go przekazać, a następnie przekazać dyrektorowi. Wtedy po prostu wywoła metodę na dyrektora, przekazując wszystkie dane. Przykład, który uważam, że książka Gang of Four służyła do konwersji dokumentu do różnych formatów. Również nie sądzę, że złożoność obiektu koniecznie oddziela wzór fabryczny od konstruktora. –

7

Kilka bardzo dobrych odpowiedzi już tutaj. Po prostu oferuję analogię.

Załóżmy, że potrzebujesz nowego biurka do swojego nowego biura. Idziesz do "fabryki" i widzisz selekcje, a następnie wybierasz jedną z półek. Jeśli pasuje do twoich potrzeb, świetnie!

Teraz masz większe biuro o naprawdę fantazyjnych ścianach. Teraz potrzebujesz biurka z dopasowanym kształtem do Twojego biura. I chcesz inne nogi pasujące do reszty mebli, a także pasujące do nowego fotela Aeron.

Wracasz do tej samej fabryki, bez powodzenia. Idziesz do stolarza, który potrafi "zbudować", co chcesz. Podajesz swoje specyfikacje i wymagania, a "budowniczy" poinformuje Cię o pewnych ograniczeniach. Po kilku iteracjach masz idealne biurko!

Ok, lame historia, ale po prostu, aby rozjaśnić rzeczy: P

2

Builder jest odwrócenie sterowania, jak Wzorca Template Method. Różne funkcje w twoim konkretnym konstruktorze to konfigurowalne kroki w procesie. Abstract Factory to "sprawiedliwy" polimorfizm, w którym wynikiem jest nowo zbudowany obiekt. Różne funkcje w konkretnej fabryce to różne modyfikowalne procesy, z których każdy prawdopodobnie powoduje inny obiekt.

Potrzebujecie więc budowniczego, gdy będziecie potrzebować wspólnej ogólnej "fabuły" do konstruowania swoich obiektów, ale z indywidualnymi "scenami" w obrębie tego wątku jest inny. Potrzebujesz fabryki, jeśli niekoniecznie jest coś wspólnego między różnymi implementacjami.

Wydaje mi się, że można użyć obu naraz, a abstrakcyjna fabryka działa jako reżyser w schemacie Budowniczego, a każda konkretna fabryka kieruje tym wszystkim inaczej. Jednak, że wykracza poza „serwetka” granicy diagramów UML ;-)

0

Więcej informacji na temat kiedy użyć wzoru Builder i jego zalety powinieneś sprawdzić mój post na innym podobnym pytaniem here

1

Rozważmy analogię.

Jesteś w sieci fast food, gdzie fast food, który rzeczywiście dostajesz, jest dość skomplikowany. Nie tylko jest to skomplikowane, ale tylko niektóre osoby mogą przyjmować zamówienia na określone rodzaje żywności. Teraz tego nie wiesz, ponieważ kierownik sklepu postanowił postawić jedną osobę za jedną kasą. Ale jeśli spojrzysz na niego uważnie, to jest to zaawansowany hologram, ponieważ jest "abstrakcyjny" "abstrakcyjny". Streszczenie zleceniodawca. Teraz, gdy mówisz do hologramu i umieszczasz swoje zamówienie, komputer hologramowy przekierowuje (polimorfizm), który zamienia się na implant w mózgu człowieka przyjmującego zamówienie. Implant sprawia, że ​​człowiek faktycznie uderza w celu do prawdziwego rejestru. Niewiele z tych ludzkich istot, o których mowa w hologramie, jest kontrolowanych przez umysł. Teraz, kiedy prawdziwy człowiek uderza w kolejność, zostaje wysłany do komputera z tyłu, gdzie znajduje się linia montażowa, lub "budowniczy", dla każdego rodzaju budowanej żywności. Zamówienia są wysyłane na różne rodzaje linii montażowych w oparciu o człowieka i jego kasę.

Hologram jest więc abstrakcyjną fabryką, ludzie kontrolowani przez umysł w rejestrach to konkretne fabryki, a linie montażowe to budowniczowie. W ten sposób można faktycznie wizualizować przepływ abstrakcyjnej fabryki pracującej z wzorcem budowniczym. Czasami najlepiej jest zobaczyć, jak współdziałają wzorce projektowe, aby zobaczyć, jak się różnią.

Jeśli szukasz dodatkowego kredytu, spróbuj wdrożyć to za pomocą generycznych. Nie wymaga tak wiele kodu, jak mogłoby się wydawać.

0

W praktyce prawdopodobnie użyjesz DI + IOC, aby zrobić to, co zrobił budowniczy. FYI.

+1

DI i IOC są przeznaczone do różnych celów - do luźnego połączenia. gdzie jako Builder zapewnia interfejs do tworzenia złożonych obiektów o różnej reprezentacji. – Brainchild

0

Dobre odpowiedzi, chciałbym dodać moje w nadziei, że odkrywam, że moje zrozumienie jest poprawne.

Jeśli masz nowe biuro i potrzebujesz tylko nowych biurek, możesz użyć Buildera. Biurko zawsze będzie biurkiem, ale istnieje wiele różnych konfiguracji biurka, tj. Rozmiar, kształt, obecność schowka, szuflady itp.

Jeśli masz nowe biuro, a wnętrze jest zupełnie puste Potrzebowalibyście różnych przedmiotów i użyliby Fabryki Abstrakcyjnej, która tworzy Meble, z której opada nasze Biurko. W tym przypadku Desk, jak wiemy, jest obiektem "złożonym", więc używa wzorca Buildera, ale tutaj jest częścią reżyserii Abstract Factory. The Abstract Factory tworzy również proste obiekty, takie jak bardzo specyficzne lampy (StraightFunkyLamp), za pośrednictwem klasy StraightFunkyLampFactory.

Powiązane problemy