Kiedy dobrym pomysłem jest stosowanie metod fabrycznych w obiekcie zamiast klasy Factory?
design-patterns
factory
factory-pattern
factory-method
Ravindra babu
źródło
źródło
Odpowiedzi:
Lubię myśleć o wzorach projektowych w kategoriach tego, że moje zajęcia są „ludźmi”, a wzorce są sposobem, w jaki ludzie rozmawiają ze sobą.
Tak więc według mnie wzór fabryczny jest jak biuro pośrednictwa pracy. Masz kogoś, kto będzie potrzebował zmiennej liczby pracowników. Ta osoba może znać pewne informacje na temat zatrudnionych osób, ale to wszystko.
Kiedy potrzebują nowego pracownika, dzwonią do agencji pośrednictwa pracy i mówią im, czego potrzebują. Teraz, aby faktycznie kogoś zatrudnić , musisz wiedzieć wiele rzeczy - korzyści, weryfikację uprawnień itp. Ale osoba zatrudniająca nie musi nic o tym wiedzieć - agencja rekrutacyjna zajmuje się tym wszystkim.
W ten sam sposób korzystanie z fabryki pozwala konsumentowi tworzyć nowe obiekty bez konieczności poznawania szczegółów ich tworzenia ani zależności od nich - muszą jedynie podać informacje, których naprawdę potrzebują.
Tak więc teraz konsument ThingFactory może uzyskać Rzecz bez konieczności znajomości zależności Rzeczy, z wyjątkiem danych łańcuchowych, które pochodzą od konsumenta.
źródło
within an object instead of a Factory class
. Myślę, że miał na myśli scenariusz, w którym uczynisz ctor prywatnym i użyjesz metody statycznej, aby utworzyć instancję klasy (stworzyć obiekt). Aby jednak podążać za tym przykładem, należy najpierw utworzyć instancjęThingFactory
klasy, aby uzyskaćThing
obiekty, co powoduje, że działa toFactory class
poprawnie.Metody fabryczne należy traktować jako alternatywę dla konstruktorów - głównie wtedy, gdy konstruktory nie są wystarczająco ekspresyjne, tj.
nie jest tak wyrazisty jak:
Klasy fabryczne są przydatne, gdy potrzebujesz skomplikowanego procesu konstruowania obiektu, gdy konstrukcja wymaga zależności, której nie chcesz dla rzeczywistej klasy, gdy potrzebujesz konstruować różne obiekty itp.
źródło
Jedną z sytuacji, w której osobiście uważam, że osobne klasy Factory mają sens, jest to, że ostateczny obiekt, który próbujesz stworzyć, opiera się na kilku innych obiektach. Np. W PHP: Załóżmy, że masz
House
obiekt, który z kolei ma aKitchen
iLivingRoom
obiekt, aLivingRoom
obiekt maTV
obiekt wewnątrz, jak również.Najprostszym sposobem na osiągnięcie tego jest utworzenie przez każdy obiekt swoich dzieci na podstawie metody konstruowania, ale jeśli właściwości są względnie zagnieżdżone, gdy
House
tworzenie się nie powiedzie, prawdopodobnie poświęcisz trochę czasu na wyodrębnienie tego, co nie działa.Alternatywą jest wykonanie następujących czynności (wstrzyknięcie zależności, jeśli podoba Ci się wymyślny termin):
Tutaj, jeśli proces tworzenia
House
awarii kończy się niepowodzeniem, jest tylko jedno miejsce do patrzenia, ale konieczność korzystania z tego fragmentu za każdym razem, gdy chce się nowego,House
jest daleka od wygody. Wejdź do fabryk:Dzięki fabryce proces tworzenia a
House
jest abstrakcyjny (w tym sensie, że nie musisz tworzyć i konfigurować każdej zależności, gdy chcesz tylko utworzyć aHouse
), a jednocześnie scentralizowany, co ułatwia utrzymanie. Są inne powody, dla których korzystanie z oddzielnych fabryk może być korzystne (np. Testowalność), ale ten konkretny przypadek użycia znajduję, aby najlepiej zilustrować, w jaki sposób klasy fabryczne mogą być przydatne.źródło
HouseFactory
klasie?create
metody. Np. Jeśli twójHouse
zawsze będzie miał taki sam rodzaj,LivingRoom
sensowne może być zapisanie jego parametrów w klasie fabrycznej zamiast podania ich jako argumentu. Lub możesz podaćtype
argument do swojejHouseFactory::create
metody, jeśli masz kilka rodzajówLivingRoom
si i masz przełącznik z parametrami zakodowanymi na stałe dla każdego typu.Ważne jest, aby wyraźnie rozróżnić pomysł za pomocą metody fabrycznej lub fabrycznej. Oba mają na celu rozwiązywanie wzajemnie wykluczających się różnych problemów związanych z tworzeniem obiektów.
Powiedzmy konkretnie o „metodzie fabrycznej”:
Po pierwsze, kiedy tworzysz bibliotekę lub interfejsy API, które z kolei będą wykorzystywane do dalszego rozwoju aplikacji, wówczas metoda fabryczna jest jednym z najlepszych wyborów wzorca tworzenia. Powód za; Wiemy, że kiedy utworzyć obiekt o wymaganych funkcjach, ale typ obiektu pozostanie niezdecydowany lub zostanie podjęta decyzja o przekazaniu parametrów dynamicznych .
Chodzi o to, że w przybliżeniu to samo można osiągnąć przy użyciu samego wzorca fabrycznego, ale jedna wielka wada wprowadzi się do systemu, jeśli wzorzec fabryczny zostanie użyty do wyżej wymienionego problemu, jest to, że twoja logika tworzenia różnych obiektów (obiektów podklas) będzie bądź specyficzny dla niektórych warunków biznesowych, więc w przyszłości, gdy będziesz musiał rozszerzyć funkcjonalność swojej biblioteki na inne platformy (technicznie rzecz biorąc, musisz dodać więcej podklas podstawowego interfejsu lub klasy abstrakcyjnej, aby fabryka zwróciła te obiekty oprócz istniejącej na podstawie niektórych parametrów dynamicznych), a następnie za każdym razem, gdy trzeba zmienić (rozszerzyć) logikę klasy fabrycznej, co będzie kosztowne, a nie dobre z punktu widzenia projektu. Z drugiej strony, jeśli „metoda fabryczna”
źródło
Przydają się również, gdy potrzebujesz kilku „konstruktorów” o tym samym typie parametru, ale o innym zachowaniu.
źródło
Dobrym pomysłem jest stosowanie metod fabrycznych wewnątrz obiektu, gdy:
Dobrym pomysłem jest użycie abstrakcyjnej klasy fabrycznej, gdy:
źródło
UML od
Produkt: Definiuje interfejs obiektów tworzonych przez metodę Factory.
Produkt betonowy: Implementuje interfejs produktu
Twórca: Deklaruje metodę Factory
ConcreateCreator: implementuje metodę Factory w celu zwrócenia instancji ConcreteProduct
Stwierdzenie problemu: Utwórz fabrykę gier za pomocą metod fabrycznych, które definiują interfejs gry.
Fragment kodu:
wynik:
Ten przykład pokazuje
Factory
klasę, implementującFactoryMethod
.Game
jest interfejsem dla wszystkich rodzajów gier. Definiuje złożoną metodę:createGame()
Chess, Ludo, Checkers
są różne warianty gier, które zapewniają implementację docreateGame()
public Game getGame(String gameName)
jestFactoryMethod
wIGameFactory
klasieGameFactory
wstępnie tworzy różne typy gier w konstruktorze. ImplementujeIGameFactory
metodę fabryczną.Nazwa gry jest przekazywana jako argument wiersza poleceń do
NotStaticFactoryDemo
getGame
inGameFactory
akceptuje nazwę gry i zwraca odpowiedniGame
obiekt.Fabryka:
FactoryMethod
Przypadek użycia:
Kiedy używać:
Client
nie wie, jakie konkretne klasy będzie trzeba utworzyć w czasie wykonywania, ale chce tylko uzyskać klasę, która wykona zadanie.źródło
getArea()
Nie jest to metoda fabryki w ogóle .To naprawdę kwestia gustu. Klasy fabryczne można w razie potrzeby wyodrębnić / powiązać, podczas gdy metody fabryczne są lżejsze (a także zwykle są testowalne, ponieważ nie mają określonego typu, ale będą wymagały znanego punktu rejestracji, podobnego do usługi lokalizator, ale do lokalizowania metod fabrycznych).
źródło
Klasy fabryczne są przydatne, gdy zwracany typ obiektu ma prywatny konstruktor, gdy różne klasy fabryczne ustawiają różne właściwości zwracanego obiektu lub gdy określony typ fabryki jest sprzężony z jego zwracanym typem konkretnym.
WCF używa klas ServiceHostFactory do pobierania obiektów ServiceHost w różnych sytuacjach. Standardowy ServiceHostFactory jest używany przez IIS do pobierania instancji ServiceHost dla .svc plików , ale WebScriptServiceHostFactory jest używany dla usług, które zwracają serializacje do klientów JavaScript. Usługi danych ADO.NET mają swoje własne DataServiceHostFactory, a ASP.NET ma ApplicationServicesHostFactory, ponieważ ich usługi mają prywatnych konstruktorów.
Jeśli masz tylko jedną klasę, która pochłania fabrykę, możesz po prostu użyć metody fabrycznej w tej klasie.
źródło
Rozważ scenariusz, w którym musisz zaprojektować klasę zamówienia i klienta. Dla uproszczenia i wstępnych wymagań nie czujesz potrzeby fabryki dla klasy Order i wypełnij swoją aplikację wieloma oświadczeniami „new Order ()”. Wszystko działa dobrze.
Teraz pojawia się nowe wymaganie, że obiekt zamówienia nie może zostać utworzony bez skojarzenia klienta (nowa zależność). Teraz masz następujące uwagi.
1- Tworzysz przeciążenie konstruktora, które będzie działać tylko w przypadku nowych implementacji. (Nie do zaakceptowania). 2- Zmieniasz podpisy Order () i zmieniasz każde wywołanie. (Nie jest to dobra praktyka i prawdziwy ból).
Zamiast tego Jeśli utworzyłeś fabrykę dla klasy zamówień, musisz zmienić tylko jeden wiersz kodu i możesz zacząć. Sugeruję klasę fabryczną dla prawie każdego skojarzenia. Mam nadzieję, że to pomaga.
źródło
jeśli chcesz stworzyć inny obiekt pod względem użytkowania. To jest użyteczne.
źródło
Każda klasa odraczająca tworzenie obiektu do swojej podklasy dla obiektu, z którym musi pracować, może być postrzegana jako przykład wzorca fabrycznego.
Wspominałem szczegółowo w innej odpowiedzi na https://stackoverflow.com/a/49110001/504133
źródło
Myślę, że będzie to zależeć od luźnego stopnia sprzężenia, który chcesz wprowadzić do swojego kodu.
Metoda fabryczna oddziela rzeczy bardzo dobrze, ale klasa fabryczna nr.
Innymi słowy, łatwiej jest zmieniać rzeczy, jeśli używasz metody fabrycznej niż w przypadku prostej fabryki (znanej jako klasa fabryczna).
Spójrz na ten przykład: https://connected2know.com/programming/java-factory-pattern/ . Teraz wyobraź sobie, że chcesz przynieść nowe zwierzę. W klasie Factory musisz zmienić fabrykę, ale w metodzie fabrycznej nie, musisz tylko dodać nową podklasę.
źródło
Klasy fabryczne są bardziej ciężkie, ale dają pewne korzyści. W przypadkach, gdy musisz zbudować swoje obiekty z wielu surowych źródeł danych, pozwalają one na enkapsulację tylko logiki budynku (i być może agregacji danych) w jednym miejscu. Tam można go przetestować abstrakcyjnie, nie zajmując się interfejsem obiektowym.
Uznałem to za użyteczny wzorzec, szczególnie tam, gdzie nie jestem w stanie zastąpić i nieadekwatnej ORM i chcę wydajnie tworzyć instancje wielu obiektów z połączeń DB lub procedur przechowywanych.
źródło
Porównuję fabryki do koncepcji bibliotek. Na przykład możesz mieć bibliotekę do pracy z liczbami i inną do pracy z kształtami. Możesz przechowywać funkcje tych bibliotek w logicznie nazwanych katalogach jako
Numbers
lubShapes
. Są to typy ogólne, które mogą obejmować liczby całkowite, liczby zmiennoprzecinkowe, dobule, długie lub prostokąty, koła, trójkąty, pięciokąty w przypadku kształtów.Petter w fabryce wykorzystuje polimorfizm, wstrzykiwanie zależności i odwracanie kontroli.
Deklarowanym celem Wzorów Fabrycznych jest:
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Powiedzmy, że budujesz system operacyjny lub platformę i budujesz wszystkie dyskretne komponenty.
Oto prosty przykład koncepcji wzorca fabrycznego w PHP. Może nie jestem w 100% na tym wszystkim, ale ma to służyć jako prosty przykład. Nie jestem ekspertem.
źródło
NumbersFactory::makeNumber( 'float', 12.5 );
sprawia, że mówię,new Float(12.5);
jeśli wiem, że potrzebujęFloat
? Tego nie rozumiem w fabrykach ... o co chodzi?