Dołączam tabelę hierarchii hermetyzacji kilku wzorców projektowych GoF, aby pomóc wyjaśnić różnice między tymi dwoma wzorcami. Mam nadzieję, że lepiej ilustruje to, co zawiera każdy z nich, więc moje wyjaśnienie ma więcej sensu.
Po pierwsze, hierarchia zawiera zakres, do którego ma zastosowanie dany wzorzec lub odpowiedni wzorzec, który ma zostać użyty do hermetyzacji pewnego poziomu szczegółowości, w zależności od tego, od której strony tabeli zaczynasz.
Jak widać z tabeli, obiekt Strategy Pattern ukrywa szczegóły implementacji algorytmu, więc użycie innego obiektu strategii będzie wykonywać tę samą funkcjonalność, ale w inny sposób. Każdy obiekt strategii może być zoptymalizowany pod kątem konkretnego czynnika lub działać na jakimś innym parametrze; a dzięki zastosowaniu wspólnego interfejsu kontekst może bezpiecznie współpracować z każdym z nich.
Wzorzec poleceń zawiera znacznie mniejszy poziom szczegółowości niż algorytm. Koduje szczegóły potrzebne do wysłania wiadomości do obiektu: odbiornik, selektor i argumenty. Zaletą zobiektywizowania tak niewielkiej części wykonania procesu jest to, że takie komunikaty mogą być wywoływane w różnych punktach czasu lub lokalizacji w ogólny sposób bez konieczności kodowania ich szczegółów. Pozwala na wywoływanie wiadomości jeden lub więcej razy lub przekazywanie ich do różnych części systemu lub wielu systemów bez konieczności poznania szczegółów konkretnego wywołania przed wykonaniem.
Jak to jest typowe dla wzorców projektowych, nie wymagają one, aby wszystkie implementacje były identyczne w szczegółach, aby nosić nazwę wzoru. Szczegóły mogą się różnić w implementacji oraz w tym, jakie dane są zakodowane w obiekcie w porównaniu z argumentami metody.
Strategie obejmują algorytmy. Polecenia oddzielają nadawcę od odbiorcy żądania, zamieniają żądanie w obiekt.
Jeśli to algorytm, jak coś zostanie zrobione, użyj strategii. Jeśli chcesz oddzielić wywołanie metody od jej wykonania, użyj Command. Polecenia są często używane podczas kolejkowania wiadomości do późniejszego wykorzystania, na przykład zadania lub transakcji.
źródło
Odpowiadając na bardzo stare pytanie. (czy ktoś widzi najnowsze odpowiedzi zamiast większości głosów?)
Jest to uzasadnione zamieszanie z powodu podobieństw. Zarówno strategie, jak i polecenia wykorzystują hermetyzację . Ale to nie czyni ich takimi samymi.
Kluczową różnicą jest zrozumienie, co jest hermetyzowane. Zasada OO, od której zależą oba wzorce, to Hermetyzuj to, co się zmienia .
W przypadku strategii różni się algorytm . Na przykład jeden obiekt strategii wie, jak wyprowadzić dane do pliku XML, podczas gdy drugi wyprowadza, powiedzmy, JSON. Różne algorytmy są przechowywane ( zamknięte ) w różnych klasach. To takie proste.
W przypadku polecenia, to, co się różni, to samo żądanie . Żądanie może pochodzić z adresu
File Menu > Delete
lubRight Click > Context Menu > Delete
lubJust Delete Button pressed
. We wszystkich trzech przypadkach można wygenerować 3 obiekty poleceń tego samego typu. Te obiekty poleceń reprezentują tylko 3 żądania usunięcia; nie algorytm usuwania. Ponieważ żądania to teraz kilka obiektów, moglibyśmy łatwo nimi zarządzać. Nagle zapewnienie funkcji, takich jak cofanie lub ponawianie, stało się trywialne.Nie ma znaczenia, w jaki sposób polecenie implementuje żądaną logikę. Podczas wywoływania funkcji execute () może zaimplementować algorytm wyzwalający usunięcie lub nawet delegować go do innych obiektów, a nawet delegować do strategii. To tylko szczegół implementacji wzorca polecenia. Dlatego nazywa się go poleceniem, chociaż nie jest to uprzejmy sposób na żądanie : -)
Porównaj to ze strategią; ten wzorzec dotyczy tylko rzeczywistej logiki, która jest wykonywana. Jeśli to zrobimy, pomoże to osiągnąć różne kombinacje zachowań przy minimalnym zestawie klas, zapobiegając w ten sposób eksplozji klas.
Myślę, że Command pomaga nam poszerzyć naszą wiedzę na temat hermetyzacji, podczas gdy strategia zapewnia naturalne wykorzystanie hermetyzacji i polimorfizmu.
źródło
Sposób, w jaki na to patrzę, jest taki, że masz wiele sposobów robienia tego samego, każdy z nich jest strategią, a coś w czasie wykonywania określa, która strategia zostanie wykonana.
Może najpierw wypróbuj StrategyOne, jeśli wyniki nie są wystarczająco dobre, wypróbuj StrategyTwo ...
Polecenia są powiązane z różnymi rzeczami, które muszą się wydarzyć, na przykład TryToWalkAcrossTheRoomCommand. To polecenie zostanie uruchomione, gdy jakiś obiekt spróbuje przejść przez pokój, ale w środku może wypróbować StrategyOne i StrategyTwo, próbując przejść przez pokój.
znak
źródło
Moim zdaniem mogę się mylić, ale traktuję polecenie jako funkcję do wykonania lub reakcję. Powinno być co najmniej dwóch graczy: ten, który żąda akcji, i ten, który ją wykonuje. GUI jest typowym przykładem dla wzorca poleceń:
Polecenie jest zwykle ograniczone do jakiegoś zakresu lub obszaru biznesowego, ale nie jest konieczne: możesz mieć polecenia, które wystawiają rachunek, uruchamiają rakietę lub usuwają plik implementujący ten sam interfejs (np. Pojedynczą
execute()
metodę) w jednej aplikacji. Często polecenia zawierają się same, więc nie potrzebują niczego od wykonawcy do przetworzenia zadania, do którego mają zamiar (wszystkie niezbędne informacje są podawane w czasie tworzenia), czasami polecenia są zależne od kontekstu i powinny być w stanie wykryć ten kontekst ( Polecenie Backspace powinno znać pozycję kursora w tekście, aby poprawnie usunąć poprzedni znak; Polecenie wycofania powinno wykryć bieżącą transakcję do wycofania; ...).Strategia jest nieco inna: to jest bardziej związana z pewnym obszarze. Strategia może definiować regułę formatowania daty (w UTC? Specyficzne dla ustawień regionalnych?) (Strategia „formatowania daty”) lub obliczania kwadratu dla figury geometrycznej (strategia „kalkulatora kwadratu”). Strategie są w tym sensie obiektami wagi lotnej, które przyjmują dane jako dane wejściowe („data”, „figura”,…) i na ich podstawie podejmują jakąś decyzję. Być może nie najlepszy, ale dobrym przykładem strategii jest ta związana z
javax.xml.transform.Source
interfejsem: w zależności od tego, czy przekazany obiekt jest,DOMSource
czySAXSource
teżStreamSource
strategia (w tym przypadku = transformator XSLT) zastosuje inne reguły do jego przetworzenia. Wdrożenie może być prosteswitch
lub obejmować wzorzec Łańcucha odpowiedzialności .Ale rzeczywiście jest coś wspólnego między tymi dwoma wzorcami: polecenia i strategie zawierają algorytmy w tym samym obszarze semantycznym.
źródło
Komenda:
Podstawowe składniki:
execute()
Przepływ pracy:
Klient wywołuje Invoker => Invoker wywołuje ConcreteCommand => ConcreteCommand wywołuje metodę Receiver , która implementuje abstrakcyjną metodę Command .
Zaleta : Klient nie ma wpływu na zmiany w poleceniu i odbiorniku. Invoker zapewnia luźne powiązanie między klientem a odbiorcą. Możesz uruchomić wiele poleceń z tym samym Invokerem.
Wzorzec poleceń pozwala na wykonanie polecenia na różnych odbiornikach przy użyciu tego samego Invokera . Invoker nie zna typu odbiorcy
Aby lepiej zrozumieć koncepcje, zapoznaj się z tym artykułem w JournalDev autorstwa Pankaja Kumara i artykule dzone autorstwa Jamesa Sugrue, oprócz linku do Wikipedii.
Możesz użyć wzorca polecenia , aby
Odłącz wywołującego i odbiorcę polecenia
Zaimplementuj mechanizm wywołania zwrotnego
Wdrażaj funkcje cofania i ponawiania
Prowadź historię poleceń
java.lang.Thread
jest jedną dobrą implementacją wzorca polecenia . Możesz traktować Thread jako wywołującego i klasę implementującą Runnable jako ConcreteCommonad / Receiver, arun()
metodę jako Command .Wersja wzorca poleceń Cofnij / Ponów można przeczytać w artykule Theodore Norvell
Strategia:
Wzorzec strategii jest bardzo łatwy do zrozumienia. Użyj tego wzoru, gdy
Istnieje wiele implementacji algorytmu, a implementacja algorytmu może ulec zmianie w czasie wykonywania w zależności od określonych warunków .
Weźmy na przykład składnik Opłaty w systemie rezerwacji linii lotniczych
Linie lotnicze chciałyby oferować różne taryfy w różnych okresach - w miesiącach szczytu i poza nim. W pozaszczytowe dni w podróży chce stymulować popyt, oferując atrakcyjne rabaty.
Kluczowe wnioski dotyczące wzorca strategii :
Powiązane posty z przykładami kodu:
Używanie wzorca Command Design
Przykład wzorca strategii ze świata rzeczywistego
źródło
Dla mnie różnica polega na intencji. Implementacje obu wzorców są dość podobne, ale mają różne cele:
W przypadku strategii komponent korzystający z obiektu wie, co robi obiekt (i użyje go do wykonania części własnej pracy), ale nie obchodzi go, jak to robi.
W przypadku polecenia komponent używający obiektu nie wie, co robi polecenie, ani jak to robi - po prostu wie, jak je wywołać. Zadaniem dzwoniącego jest po prostu uruchomienie polecenia - przetwarzanie wykonywane przez polecenie nie stanowi części podstawowej pracy dzwoniącego.
Na tym polega różnica - czy obiekt korzystający z komponentu faktycznie wie lub dba o to, co robi komponent? W większości przypadków można to ustalić na podstawie tego, czy obiekt wzorca zwraca wartość do swojego wywołującego. Jeśli wywołujący dba o to, co robi obiekt wzorca, prawdopodobnie będzie chciał, aby coś zwrócił i będzie to strategia. Jeśli nie dba o jakąkolwiek zwracaną wartość, prawdopodobnie jest to Polecenie (uwaga, coś w rodzaju wywoływanego języka Java jest nadal poleceniem, ponieważ chociaż zwraca wartość, wywołujący nie dba o wartość - po prostu przekazuje ją z powrotem do tego, co pierwotnie dostarczało polecenie).
źródło