Z wzorców projektowych „Gang of Four” jest metoda Factory:
class Factory(product)
case product
when a
new A
when b
new B
when c
new C
end
new Factory(a)
Dlaczego jest to bardziej przydatne niż o trzech klasach a
, b
oraz c
i nazywając je indywidualnie?
Odpowiedzi:
Ponieważ twój przykład nie jest wystarczająco skomplikowany. W przypadku tak prostego scenariusza nie ma nawet sensu stosowanie zaawansowanego wzorca.
Ale jeśli musisz wiedzieć więcej niż produkt, aby zbudować A, B lub C, i nie możesz mieć bezpośredniego dostępu do tej wiedzy, to jest to przydatne. Następnie wykorzystujesz fabrykę jako centrum wiedzy do produkcji potrzebnych przedmiotów.
Być może te obiekty potrzebują odniesienia do jakiegoś obiektu X, który może dostarczyć fabryka, ale twój kod w miejscu, w którym chcesz zbudować A, B lub C, nie może lub nie powinien mieć dostępu do X. Może gdy masz X tworzysz A i B, ale jeśli masz typ Y, to tworzysz C.
Weź również pod uwagę, że niektóre obiekty mogą wymagać 20 zależności do utworzenia; co wtedy? Problemem może być polowanie na te zależności w miejscu, w którym nie powinny być one dostępne.
źródło
Wzorzec fabryczny jest zwykle bardziej złożony. Fabryka decyduje o określonych kryteriach, które wystąpienie utworzyć / zwrócić. Zamiast tego, gdy nie korzystasz z fabryki, kod ten będzie wielokrotnie używany w kilku lokalizacjach w kodzie.
Jako przykład rozważ następujące kwestie: musisz załadować dane z DB, ale masz jeden centralny DB do integracji z dużą ilością danych i jeden mniejszy w pamięci na każdym dev-PC. W kodzie pytasz fabrykę dostać się DB-uchwyt i powraca fabrycznych jedną z tych, w zależności od np plik konfiguracyjny.
źródło
Wzorzec metody fabrycznej wyodrębnia proces decyzyjny z klasy wywołującej. Ma to kilka zalet:
Ponowne użycie. Jeśli chcę utworzyć instancję w wielu miejscach, nie muszę powtarzać mojego warunku, więc kiedy przychodzę dodać nową klasę, nie ryzykuję, że ją pominę.
Testowalność jednostkowa. Mogę napisać 3 testy dla fabryki, aby upewnić się, że zwraca prawidłowe typy we właściwych warunkach, wtedy moja klasa wywołująca musi zostać przetestowana, aby sprawdzić, czy wywołuje fabrykę, a następnie wymagane metody na zwróconej klasie. Nie musi nic wiedzieć o realizacji samej fabryki ani konkretnych klasach.
Rozciągliwość. Gdy ktoś decyduje, że musimy dodać nową klasę D do tej fabryki, nigdy nie trzeba mówić o żadnym kodzie wywołującym, ani testach jednostkowych, ani implementacji. Po prostu tworzymy nową klasę D i rozszerzamy naszą metodę fabryczną. To jest właśnie definicja zasady otwartego i zamkniętego .
Możesz nawet utworzyć nową klasę fabryczną i sprawić, by były wymienialne podczas pracy, jeśli sytuacja tego wymaga - na przykład, jeśli chcesz mieć możliwość włączania i wyłączania klasy D podczas testowania. Natrafiłem na tę sytuację tylko raz, ale była ona bardzo przydatna.
Jak już powiedziano, Wzorzec Fabryczny nie zawsze jest właściwą drogą. Ale gdziekolwiek zobaczysz warunkową instancję, powinieneś się nad tym zastanowić.
źródło
Kluczowe zalety wzoru Factory są dwojakie:
Miejsca, które wymagają wdrożenia produktu, nie muszą wiedzieć, jak je zbudować. Fabryka przechowuje te informacje.
Czy chcesz wiedzieć, jakie argumenty przekazać konkretnemu konstruktorowi? Lub jakie zależności musisz wprowadzić? Lub jak zarejestrować klasę implementacji w bazie danych po jej pełnej konfiguracji? Nie? Niech fabryka zajmie się tymi wszystkimi sprawami.
Miejsca, które wymagają implementacji produktu, nie muszą wiedzieć w czasie opisu modułu (tj. W czasie kompilacji), jak nazywa się klasa implementacji.
Dlatego
a
nie trzeba mieć z tym nic wspólnegoA
; „co zbudować” można opisać w kategoriach pożądanych właściwości niefunkcjonalnych, a nie tylko samej nazwy. Jest to o wiele bardziej elastyczne.Minusem jest to, że tam, gdzie wiesz, co zrobić i jak to zrobić, stajesz się bardziej złożony, gdy używasz fabryki. Rozwiązanie tego problemu jest proste: nie używaj fabryki, jeśli nie ma to sensu!
źródło
Chciałbym myśleć o wzorcach projektowych w kategoriach bycia „ludźmi”, a wzorce to sposoby, w jakie ludzie rozmawiają ze sobą.
Tak więc według mnie wzór fabryki jest jak agencja zatrudnienia. 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 zatrudnienia 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ą.
Kurtuazja
źródło
Wzorzec fabryczny jest najbardziej nadużywanym i nadużywanym wzorem projektowym.
Natknąłem się na wiele przypadków, w których klasa Factory jest kodowana, gdy prosty konstruktor byłby odpowiedni.
Nie używaj klasy fabrycznej, chyba że:
źródło
Użyj metody fabrycznej podczas tworzenia podklasy, a kod klienta nie powinien odpowiadać za podejmowanie decyzji, która konkretna podklasa jest tworzona.
Jest to użyteczne, ponieważ zapobiega konieczności zmiany kodu klienta, gdy trzeba zmienić typ instancji klasy. Zmiana istniejącego kodu jest złą praktyką, ponieważ zazwyczaj jest podatna na błędy.
Przykładem mogą być podklasy, w których każdy sortuje dane w porządku rosnącym, ale w inny sposób. Każdy sposób jest optymalny dla określonego rodzaju danych. np .: częściowo posortowane dane, dane, które są liczbami itp. Kod klienta to klasa, która obsługuje tylko drukowanie danych. Posiadanie kodu decydującego o tym, która klasa sortująca zostanie utworzona w klasie klienta, uczyniłaby ją złożoną klasą. Innymi słowy, ponosząc więcej niż jedną odpowiedzialność, w tym przypadku decyduje, która klasa sortowania jest optymalna i drukuje dane. Umieszczając kod decydujący o tym, która klasa sortująca zostanie utworzona w klasie Factory, rozdziela obawy, dzięki czemu nie trzeba zmieniać klasy klienta za każdym razem, gdy trzeba zmienić, która podklasa sortowania jest tworzona.
Jest to sposób na zakrycie twojego tyłka, jeśli możesz przewidzieć własne zmiany w sposobie tworzenia instancji klasy lub klasy, to warto zastosować klasy fabryczne. Pomaga skupić się na zajęciach na ich jednej odpowiedzialności, dzięki czemu mniej prawdopodobne jest, że będziesz musiał modyfikować istniejący niepowiązany kod.
źródło