Czy ktoś może mi wyjaśnić, jaka jest różnica między wzorcem metody szablonowej a wzorcem strategii?
O ile wiem, są one w 99% takie same - jedyną różnicą jest to, że wzorzec metody szablonu ma klasę abstrakcyjną jako klasę bazową, podczas gdy klasa strategii używa interfejsu implementowanego przez każdą konkretną klasę strategii.
Jednak z punktu widzenia klienta są one konsumowane dokładnie w ten sam sposób - czy to prawda?
Odpowiedzi:
Główna różnica między nimi polega na wybraniu konkretnego algorytmu.
W przypadku wzorca metody Template dzieje się to w czasie kompilacji przez podklasę szablonu. Każda podklasa zapewnia inny konkretny algorytm, implementując abstrakcyjne metody szablonu. Gdy klient wywołuje metody interfejsu zewnętrznego szablonu, szablon wywołuje swoje metody abstrakcyjne (jego interfejs wewnętrzny) zgodnie z wymogami wywołania algorytmu.
W przeciwieństwie do tego wzorzec strategii pozwala na wybór algorytmu w czasie wykonywania przez zawieranie . Konkretne algorytmy są implementowane przez oddzielne klasy lub funkcje, które są przekazywane do strategii jako parametr do jej konstruktora lub do metody ustawiającej. Algorytm wybrany dla tego parametru może zmieniać się dynamicznie w zależności od stanu programu lub danych wejściowych.
W podsumowaniu:
źródło
if (config.useAlgoA) impl = new AlgoA() else impl = new AlgoB()
), więc ta odpowiedź jest niepoprawna.new ConcreteAlgorithm1()
versusnew ConcreteAlgorithm2()
. Oczywiście wybór następuje w czasie wykonywania (wybranie algorytmu w czasie kompilacji oznaczałoby zakodowanie go na stałe). Główną różnicą między nimi jest sposób implementacji konkretnego algorytmu. Czy jest zaimplementowany jako podklasa czy jako oddzielny interfejs? Pierwsza z nich to szablon. Ta ostatnia to strategia. Różnicę można podsumować jako kompozycję a dziedziczenie, co jest wspólnym tematem książki GoF.Wzorzec szablonu jest używany, gdy dana operacja ma pewne niezmienne zachowanie, które można zdefiniować w kategoriach innych różnych zachowań pierwotnych. Klasa abstrakcyjna definiuje niezmienne zachowanie, podczas gdy klasy implementujące definiują metody zależne.
W strategii implementacje zachowania są niezależne - każda klasa implementująca definiuje zachowanie i nie ma między nimi współdzielonego kodu. Oba są wzorcami behawioralnymi i jako takie są konsumowane w podobny sposób przez klientów. Zwykle strategie mają jedną metodę publiczną -
execute()
metodę, podczas gdy szablony mogą definiować zestaw metod publicznych, a także zestaw wspierających prymitywów prywatnych, które muszą implementować podklasy.Te dwa wzory można z łatwością wykorzystać razem. Możesz mieć wzorzec strategii, w którym kilka implementacji należy do rodziny strategii zaimplementowanych przy użyciu wzorca szablonu.
źródło
Myślę, że Diagramy klas obu formacji pokazują różnice.
Strategia
Hermetyzuje algorytm wewnątrz klasy
Link to image
Metoda szablonu
Odroczenie dokładnych kroków algorytmu do podklasy
Link do obrazu
źródło
Prawdopodobnie masz na myśli wzorzec metody szablonowej. Masz rację, służą bardzo podobnym potrzebom. Powiedziałbym, że lepiej jest używać metody szablonowej w przypadkach, gdy masz algorytm „szablonu”, który ma zdefiniowane kroki, w których podklasy zastępują te kroki, aby zmienić niektóre szczegóły. W przypadku strategii musisz stworzyć interfejs, a zamiast dziedziczenia użyć delegacji. Powiedziałbym, że jest to nieco mocniejszy wzorzec i może lepszy zgodnie z DIP - zasadami inwersji zależności. Ma większą moc, ponieważ jasno definiujesz nową abstrakcję strategii - sposób robienia czegoś, co nie dotyczy metody szablonowej. Jeśli więc ta abstrakcja ma sens - wykorzystaj ją. Jednak użycie metody szablonowej może dać prostsze projekty w prostych przypadkach, co również jest ważne. Zastanów się, które słowa pasują lepiej: czy masz algorytm szablonu? A może kluczowe jest tutaj to, że masz abstrakcję strategii - nowy sposób robienia czegoś
Przykład metody szablonowej:
Tutaj dziedziczysz z aplikacji i zastępujesz to, co dokładnie zostanie zrobione podczas init, run i done.
Przykład strategii:
Tutaj, pisząc funkcję porównującą, nie dziedziczysz z tablicy. Array deleguje algorytm porównania do funkcji porównującej.
źródło
Podobieństwa
Wzorce strategii i metod szablonowych mają między sobą wiele podobieństw. Aby spełnić zasadę otwartego-zamkniętego i ułatwić rozszerzanie modułu oprogramowania bez zmiany jego kodu, można zastosować zarówno wzorce metody strategicznej, jak i szablonowej. Oba wzorce reprezentują oddzielenie ogólnej funkcjonalności od szczegółowej implementacji tej funkcjonalności. Jednak różnią się one nieco pod względem oferowanej szczegółowości.
Różnice
Oto niektóre z różnic, które zauważyłem podczas badania tych dwóch wzorców:
Zdjęcie pochodzi z pogryzionego bloga.
źródło
Dziedziczenie a agregacja (is-a versus has-a). To dwa sposoby na osiągnięcie tego samego celu.
To pytanie pokazuje niektóre kompromisy między wyborami: dziedziczenie a agregacja
źródło
Obie są bardzo podobne i oba są używane przez kod klienta w podobny sposób. W przeciwieństwie do tego, co mówi najpopularniejsza odpowiedź powyżej, obie pozwalają na wybór algorytmu w czasie wykonywania .
Różnica między nimi polega na tym, że podczas gdy wzorzec strategii pozwala różnym implementacjom na użycie zupełnie różnych sposobów osiągnięcia pożądanego rezultatu, wzorzec metody szablonowej określa nadrzędny algorytm (metodę „szablonową”), który jest używany do osiągnięcia wyniku - - jedyny wybór pozostawiony konkretnym implementacjom (podklasom) to pewne szczegóły wspomnianej metody szablonowej. Odbywa się to poprzez wywołanie przez metodę szablonu jednej lub więcej metod abstrakcyjnych , które są nadpisywane (tj. Implementowane) przez podklasy, w przeciwieństwie do metody szablonu, która sama nie jest abstrakcyjna i nie jest zastępowana przez podklasy .
Kod klienta wywołuje metodę template przy użyciu referencji / wskaźnika klasy abstrakcyjnej wskazującej na wystąpienie jednej z konkretnych podklas, które można określić w czasie wykonywania, tak jak przy użyciu wzorca strategii.
źródło
Metoda szablonu:
Struktura Template_method :
Strategia:
Struktura strategii :
Zapoznaj się z artykułami dotyczącymi metody szablonowej i strategii, aby lepiej zrozumieć.
Powiązane posty:
Wzorzec projektu szablonu w JDK, nie można znaleźć metody definiującej zbiór metod do wykonania w kolejności
Przykład wzorca strategii w świecie rzeczywistym
źródło
Nie, niekoniecznie są one spożywane w ten sam sposób. Wzorzec „metoda szablonu” jest sposobem dostarczania „wskazówek” przyszłym realizatorom. Mówisz im: „Wszystkie obiekty muszą mieć numer ubezpieczenia społecznego” (to trywialny przykład, ale dobrze oddaje ideę).
Wzorzec strategii umożliwia włączanie i wyłączanie wielu możliwych implementacji. Nie jest (zwykle) implementowana poprzez dziedziczenie, ale zamiast tego pozwalając wywołującemu przejść do żądanej implementacji. Przykładem może być zezwolenie na dostarczenie ShippingCalculator jednego z kilku różnych sposobów obliczania podatków (implementacja NoSalesTax i być może implementacja PercentageBasedSalesTax).
Tak więc czasami klient w rzeczywistości powie obiektowi, której strategii ma użyć. Jak w
Ale klient nigdy nie zrobiłby tego dla obiektu opartego na metodzie szablonu. W rzeczywistości klient może nawet nie wiedzieć, że obiekt jest oparty na metodzie szablonu. Te abstrakcyjne metody we wzorcu Template Method mogą być nawet chronione, w takim przypadku klient nawet nie wiedziałby, że istnieją.
źródło
Proponuję przeczytać ten artykuł. Wyjaśnia różnice na prawdziwym przykładzie.
Cytat z artykułu
źródło
Wzorzec szablonu jest podobny do wzorca strategii. Te dwa wzorce różnią się zakresem i metodologią.
Strategia jest używana, aby umożliwić dzwoniącym zmianę całego algorytmu, na przykład sposobu obliczania różnych rodzajów podatku, podczas gdy metoda szablonu służy do różnicowania kroków w algorytmie. Z tego powodu strategia jest gruboziarnista. Szablon umożliwia precyzyjniejsze kontrole w sekwencji operacji, a jednocześnie pozwala na różne implementacje tych szczegółów.
Inną główną różnicą jest to, że strategia używa delegowania, podczas gdy metoda szablonu korzysta z dziedziczenia. W strategii algorytm jest delegowany do innej klasy xxxStrategy, do której podmiot będzie miał odniesienie, ale za pomocą szablonu możesz podklasować podstawową i przesłonić metody w celu wprowadzenia zmian.
z http://cyruscrypt.blogspot.com/2005/07/template-vs-strategy-patterns.html
źródło
W strategii podklasy kierują pokazem i kontrolują algorytm. Tutaj kod jest zduplikowany we wszystkich podklasach. Znajomość algorytmu i sposobu jego implementacji jest rozłożona na wiele klas.
We wzorcu szablonu klasa bazowa ma algorytm. Maksymalizuje ponowne użycie wśród podklas. Ponieważ algorytm leży w jednym miejscu, chroni go klasa bazowa.
źródło
źródło
Wzór szablonu:
Metoda szablonowa polega na umożliwieniu podklasom redefiniowania pewnych kroków algorytmu, bez zmiany głównej struktury i kroków algorytmu zdefiniowanych w klasie bazowej. Wzorzec szablonu zwykle używa dziedziczenia, więc ogólna implementacja algorytmów może być dostarczona w klasie bazowej, którą podklasa może zastąpić w razie potrzeby.
Zauważ, że w powyższym kodzie kroki algorytmu go () będą zawsze takie same, ale podklasy mogą definiować inną receptę na wykonanie określonego kroku.
Wzorzec strategii:
Wzorzec strategii polega na umożliwieniu klientowi wyboru konkretnej implementacji algorytmów w czasie wykonywania. Wszystkie algorytmy są izolowane i niezależne, ale implementują wspólny interfejs i nie ma pojęcia o definiowaniu poszczególnych kroków w algorytmie.
Aby uzyskać pełny kod źródłowy, sprawdź moje repozytorium github .
źródło
Strategia jest prezentowana jako interfejs i metoda szablonu jako Klasa abstrakcyjna. Jest to zwykle często używane w frameworkach. np. klasa MessageSource platformy Spring Framework jest interfejsem strategii służącym do rozwiązywania komunikatów. Klient korzysta z określonej implementacji (strategii) tego interfejsu.
I abstrakcyjna implementacja tego samego interfejsu AbstractMessageSource, który ma wspólną implementację rozwiązywania komunikatów i ujawnia abstrakcyjną metodęolveCode (), aby podklasy mogły implementować je na swój sposób. AbstractMessageSource jest przykładem metody szablonowej.
http://docs.spring.io/spring/docs/4.1.7.RELEASE/javadoc-api/org/springframework/context/support/AbstractMessageSource.html
źródło
W metodzie szablonowej tego wzorca projektowego jeden lub więcej kroków algorytmu może zostać zastąpionych przez podklasy, aby umożliwić różne zachowania, zapewniając jednocześnie, że nadrzędny algorytm jest nadal przestrzegany (Wiki).
Nazwa wzorca Metoda szablonowa oznacza, czym jest. Powiedzmy, że mamy metodę CalculateSomething () i chcemy utworzyć szablon tej metody. Ta metoda zostanie zadeklarowana w klasie bazowej jako metoda niewirtualna. Powiedz, że metoda wygląda następująco.
} Implementacje metod Step1 i Step2 mogą być podane przez klasy pochodne.
We wzorcu strategii nie ma implementacji dostarczonej przez bazę (jest to powód, dla którego podstawa jest tak naprawdę interfejsem w diagramie klas)
Klasycznym przykładem jest sortowanie. Na podstawie liczby obiektów, które należy posortować, tworzona jest odpowiednia klasa algorytmu (merge, bubble, quick itp.), A cały algorytm jest hermetyzowany w każdej klasie.
Czy możemy teraz zaimplementować sortowanie jako metodę szablonową? Z pewnością możesz, ale nie znajdziesz zbyt wielu / żadnych wspólnych elementów do wyodrębnienia i umieszczenia w podstawowej implementacji. Więc to niweczy cel wzorca metody szablonowej.
źródło