Strategy¶
Przeznaczenie
- Definiuje rodziny algorytmów 
- Dokonuje ich hermetyzacji i sprawia, że stają się one wymienne 
- Pozwala na modyfikację danego algorytmu niezależnie od klienta, który tego algorytmu używa 
Kontekst
- Wiele powiązanych ze sobą klas różni się tylko zachowaniem 
- Potrzebne są różne warianty jakiegoś algorytmu 
- W algorytmie są używane dane, o których klient nie powinien wiedzieć – Strategia pozwala uniknąć ujawniania złożonych i specyficznych dla algorytmu struktur danych 
- Klasa definiuje wiele zachowań, które w operacjach są uwzględnione w postaci wielokrotnych instrukcji warunkowych 
Problem
- Chcemy dokonać hermetyzacji algorytmu w klasie i stosując składanie obiektów umożliwić wymianę implementacji algorytmu 
Struktura¶
 
Uczestnicy¶
Strategy
- deklaruje interfejs wspólny dla wszystkich obsługiwanych algorytmów 
- obiekt Context wykorzystuje ten interfejs do wykonywania algorytmu zdefiniowanego przez klasę ConcreteStrategy 
ConcreteStrategy – implementuje algorytm, wykorzystując interfejs klasy Strategy
Context
- jest konfigurowany za pomocą obiektu ConcreteStrategy 
- utrzymuje odwołanie do obiektu typu Strategy 
- może definiować interfejs umożliwiający obiektowi strategii uzyskanie dostępu do jego danych 
Współpraca¶
- Strategy i Context współdziałają w celu zaimplementowania wybranego algorytmu. 
- Klienci tworzą obiekt klasy ConcreteStrategy i przekazują go do kontekstu. 
- Kontekst przekazuje żądania od klientów do swojej strategii. 
- Klienci komunikują się wyłącznie z kontekstem. 
- Komunikacja między obiektami kontekstu i strategii: 
- w chwili wywołania kontekst może przekazać strategii wszystkie dane potrzebne do realizacji tego algorytmu, 
- kontekst przekazuje samego siebie jako argument – umożliwia to obiektowi Strategy zwrotne odwołanie się w miarę potrzeby do kontekstu. 
Konsekwencje¶
- Rodziny powiązanych ze sobą algorytmów. Hierarchie podklas Strategy definiują rodzinę algorytmów do wielokrotnego użycia przez konteksty. 
- Alternatywa dla tworzenia klas pochodnych. Enkapsulacja algorytmu w oddzielnych klasach umożliwia modyfikowanie go niezależnie od jego kontekstu – ułatwia to zmienianie go, zrozumienie go i rozszerzanie. 
- Strategie eliminują instrukcje warunkowe. Alternatywa dla stosowania instrukcji warunkowych w celu wybrania pożądanego zachowania. 
- Wybór implementacji. Zapewnienie różnych implementacji tego samego zachowania. 
- Klienci muszą być świadomi istnienia różnych strategii i różnic pomiędzy nimi – potencjalna wada. 
- Wyższe koszty związane z komunikacją między strategią a kontekstem. 
- Zwiększona liczba obiektów. 
Implementacja¶
Definiowanie interfejsów strategii (Strategy) i kontekstu (Context). Interfejsy Strategy i Context muszą umożliwić konkretnej implementacji strategii (ConcreteStrategy) dostęp do dowolnych danych, jakich będzie ona potrzebować z kontekstu (i vice versa):
- Context przesyła dane do operacji Strategy w argumentach 
- Context przesyła siebie samego jako argument, a strategia jawnie żąda danych od kontekstu 
Klasa kontekstu jest prostsza w użyciu, jeżeli użycie jej bez obiektu strategii ma sens. Implementacja strategii domyślnej – klienci nie muszą zajmować się obiektami strategii. Jeśli strategie są prostymi metodami, można zrezygnować z enkapsulacji w postaci odrębnej klasy na rzecz wskaźników do funkcji lub obiektów funkcyjnych.
Podsumowanie¶
- Obiekt klasy Strategy hermetyzuje algorytm w postaci obiektu. 
- Program wykorzystujący wzorzec Strategy może oferować wiele wersji algorytmu lub zachowania. 
- Zachowanie obiektów może się dynamicznie zmieniać w czasie wykonywania programu. 
- Delegowanie zachowania do interfejsu Strategy uniezależnia klasy korzystające z tego interfejsu od klas, które implementują zarówno ten interfejs, jak i właściwe zachowanie.