Wzornictwo strategia jest często traktowane jako substytut funkcji pierwszej klasy w językach, które ich nie posiadają.
Powiedzmy na przykład, że chcesz przekazać funkcjonalność do obiektu. W Javie musisz przekazać obiektowi inny obiekt, który zawiera pożądane zachowanie. W języku takim jak Ruby wystarczy przekazać samą funkcjonalność w postaci funkcji anonimowej.
Jednak myślałem o tym i zdecydowałem, że może Strategia oferuje coś więcej niż zwykła anonimowa funkcja.
Wynika to z faktu, że obiekt może utrzymać stan, który istnieje niezależnie od okresu, w którym działa jego metoda. Jednak sama anonimowa funkcja może utrzymać stan, który przestaje istnieć w momencie, gdy funkcja zakończy wykonywanie.
Czy w języku obiektowym, który obsługuje funkcje najwyższej klasy, wzorzec strategii ma jakąkolwiek przewagę nad używaniem funkcji?
źródło
Odpowiedzi:
Gdy język obsługuje odwołania do funkcji ( Java robi to od wersji 8 ), są one często dobrą alternatywą dla strategii, ponieważ zazwyczaj wyrażają to samo przy mniejszej składni. Istnieją jednak przypadki, w których prawdziwy obiekt może być przydatny.
Interfejs strategii może mieć wiele metod. Weźmy
RouteFindingStragegy
jako przykład interfejs , który zawiera różne algorytmy wyszukiwania trasy. Może deklarować metody takie jakRoute findShortestRoute(Node start, Node destination)
boolean doesRouteExist(Node start, Node destination)
Route[] findAllPossibleRoutes(Node start, Node destination)
Route findShortestRouteToClosestDestination(Node start, Node[] destinations)
Route findTravelingSalesmanRoute(Node[] stations)
które następnie zostałyby wdrożone przez strategię. Niektóre algorytmy wyszukiwania trasy mogą pozwalać na wewnętrzne optymalizacje dla niektórych z tych przypadków użycia, a niektóre mogą nie, więc implementator może zdecydować, jak zaimplementować każdą z tych metod.
Innym przypadkiem jest sytuacja, w której strategia ma stan wewnętrzny. Jasne, w niektórych językach zamknięcia mogą mieć stan wewnętrzny, ale kiedy stan wewnętrzny staje się bardzo złożony, często staje się bardziej elegancki, aby promować zamknięcie pełnej klasy.
źródło
Nie jest prawdą, że funkcja anonimowa może utrzymać stan, który przestaje istnieć, gdy funkcja zakończy wykonywanie.
Weź następujący przykład z Common Lisp:
Ta funkcja pobiera listę ciągów znaków i dodaje licznik do każdego elementu listy. Na przykład wywoływanie
daje
Funkcja
number-strings
wewnętrznie korzysta z funkcji anonimowej ze zmienną,counter
która przechowuje stan (bieżąca wartość licznika), która jest ponownie używana za każdym razem, gdy funkcja jest wywoływana.Ogólnie rzecz biorąc, zamknięcie można traktować jako obiekt za pomocą tylko jednej metody. Alternatywnie, obiekt jest zbiorem zamknięć, które mają te same zmienne zamknięte. Nie jestem więc pewien, czy istnieją przypadki, w których trzeba użyć obiektu zamiast zamknięcia: argumentowałbym, że oba są sposobami patrzenia na ten sam wzór z różnych perspektyw.
W szczególności wzorzec strategii wymaga obiektu z tylko jedną metodą, więc zamknięcie powinno wykonać zadanie. Ale, jak zauważył Philipp w swojej odpowiedzi, w zależności od okoliczności (stan złożony) i języków programowania można uzyskać bardziej eleganckie rozwiązanie, używając obiektów.
źródło
let
a następnie zdefiniować moje zamknięcie w nim. Zasadniczo zdefiniowałbym obiekt za pomocą jednej metody w locie. W innym języku (np. Java) może być wygodniejsze (prostsze składniowo) zdefiniowanie odpowiedniego obiektu do utrzymania stanu. Więc decydowałbym od przypadku do przypadku.To, że dwa projekty mogą rozwiązać ten sam problem, nie oznacza, że są one bezpośrednimi substytucjami.
Jeśli potrzebujesz śledzić stan w programie funkcjonalnym, nie mutujesz zmiennej zamkniętej, nawet jeśli język na to pozwala. Możesz wywołać funkcję, która przyjmuje argument jako jeden stan i zwraca nowy stan jako jego wartość zwracaną.
Twoja architektura będzie wyglądać zupełnie inaczej, ale osiągniesz ten sam cel. Nie próbuj narzucać wzorców jednego paradygmatu bezpośrednio na drugi.
źródło
Strategia to koncepcja , przydatna recepta na rozwiązanie konkretnego, powtarzającego się problemu. To nie jest konstrukcja językowa, ani też żadna forma implementacji . Zamknięcia można użyć do wdrożenia Strategii jednego dnia i Obserwatora następnego dnia.
Określenie strategii jest przede wszystkim przydatna w rozmowach z innymi programistów do zwięźle wyrazić swoje zamiary. Nie ma w tym nic magicznego.
źródło