Zastosowanie
Strategia
(ang. Strategy
) (wzorzec behawioralny) definiuje rodzinę wymiennych algorytmów (w postaci klas), które służą do rozwiązywania tego samego problemu na kilka różnych sposobów. Klient może dynamicznie wybrać strategie dla obiektu i dowolnym momencie zmienić ją na inną. Szczegóły implementacji konkretnych strategii są ukryte dla klienta, a ewentualna modyfikacja wiążę się zmianą kodu w klasie konkretnej strategii. Ponadto zwiększa możliwość niezależnego testowania strategii i klienta. W celu usprawnienia procesu wyboru strategii wzorzec ten może być łączony ze wzorcem Metoda wytwórcza
.
Ograniczenia
Ze względu na podobieństwa w strukturze, wzorzec ten może być mylony ze wzorcami Adapter
i Most
, których zastosowanie wynika z realizacji innych celów. Należy zatem się upewnić, że wybór wzorca Strategia
jest zasadny. W sytuacji, gdy obiekt kontekstu nie wymaga przekazania strategii w konstruktorze, należy zadbać o jej domyślną implementacje. Dodatkowo wzrasta koszt komunikacji między obiektami, a w przypadku wielu implementacji algorytmu powstaje wiele klas. Klient powinien znać różnicę między strategiami w celu wyboru właściwej.
Użycie
Wzorzec ten podobnie jak Adapter
wykorzystuje mechanizm delegowania operacji do innego obiektu. Ponadto używa podobnej struktury jak Most
, jednakże celem wzorca Most
jest zaprojektowanie odpowiedniej struktury klas projektu, natomiast Strategia
skupia się zmienności zachowania obiektu. Strategia
ma zastosowanie w sytuacjach, gdzie dane zadanie może zostać zrealizowane na wiele różnych sposobów, a decyzja o wyborze implementacji zapada dynamicznie.
Implementacja
Klasa kontekstu Context
zawiera referencję do obiektu klasy strategii AbstractStrategy
. Obiekt strategii może zostać wstrzyknięty przez konstruktor bądź metodę dostępową. Metoda klasy kontekstu wykorzystuje obiekt strategii w celu finalizacji operacji. Klasy strategii ConcreteStrategy1
, ConcreteStrategy2
itd. implementują metody interfejsu AbstractStrategy
.
Poniższy listing przedstawia implementację wzorca Strategia
wykorzystywaną w obiektach klasy Context
w oparciu o dwa warianty ConcreteStrategy1
oraz ConcreteStrategy2
.
Klient przed wywołaniem metody docelowej dokonuje wyboru wstrzykniętej strategii w zależności od stanu i spełnionych warunków.
Przykład
Aplikacja sklepu internetowego znajdującego się na terenie Europy obsługuje dostawę swoich produktów do różnych rejonów świata. W zależności od rejonu lub kraju wysyłki naliczane jest odpowiednia opłata celna oraz wzrasta koszt wysyłki EuropeShopping
, AmericaShopping
. Niektóre produkty ze względu na gabaryt mogą nie być dostępne do wysyłki w dane miejsce. Aplikacja automatycznie wykrywa kraj klienta i dobiera odpowiednią strategie (Shopping
) naliczania ceny całkowitej w walucie klienta (podstawową walutą jest euro). Poniższy listing prezentuje sposób realizacji doboru strategii naliczania ceny końcowej.
Użytkownik dodaje produkty do swojego koszyka, a w przypadku braku możliwości wysłania produktu do danego regionu otrzymuje stosowany komunikat. Przed przystąpieniem do potwierdzenia zamówienia następuje proces wyliczania całkowitej ceny realizacji zamówienia.
Biblioteki
Przykładem realizującym implementacje wzorca Strategia
może być metoda sort
klasy Collections
(należącej do standardowego pakietu Java
) do której wstrzykiwany jest Comparator
oraz doFilter
klasy Filter
. Wybór odpowiednich zasobów aplikacji (język, widoki, wielkości itp) w Androidzie
w swojej idei przypomina wzorzec Strategia
.