Wzorce projektowe: Strategia(Strategy)

Dzisiaj zaczynamy ostatni z operacyjnych wzorców projektowych(w końcu!!!), który zwie się Strategia(Strategy) już przy samym czytaniu tego artykułu zanim ktoś dojdzie na dół artykułu do sekcji „powiązania z innymi wzorcami” dojdzie do wniosku, że wzorzec Strategy jest bardzo podobny do wzorca State jednak różnią się one celem, ale wszystko po kolei 🙂

 

Dyskusja

Główny cel wzorca Strategy jest opisany na obrazku poniżej:

Nie no żartowałem 😂

Głównym celem wzroca Strategia(Strategy) jest rozdzielenie wielu algorytmów, zahermetyzowanie szczegółów implementacji tych algorytmów w klasach pochodnych i użycie ich do różnych sytuacji, później w konkretnych przykładach stanie się to bardziej jasne 🙂

Najważniejsze elementy w implementacji tego wzorca to:

  • Klasa Context, która ma bardzo podobne działanie jak we wzorcu State, przechowuje obiekt klasy algorytmu, nadpisuje go oraz zmienia kiedy chcemy działać już na innym algorytmie.
  • Interfejs Interface, który posiada zdefiniowane metody potrzebne do wszystkich algorytmów.
  • Klasy ConcreteStrategy dziedziczące po interfejsie Interface, które implementują konkretne algorytmy.

Wzorca Strategy możesz użyć kiedy masz dużo algorytmów, które wykonują różne funkcje, jak jest ich naprawde dużo to warto rozdzielić je, zahermetyzować i używać oddzielnie, bo później prawdopodobnie będzie ciężko je używać, ponieważ będą poplątane ze sobą.

Weźmy przykład funkcji w telefonie, tam jest tyle tych funkcji w niektórych modelach, że najlepiej będzie użyć tam wzorca Strategy to łatwiejszego zarządzania i wykorzystywania tych funkcji.

Jak widzisz wzorca Strategy podobnie jak wzorca State ma jedynie sens używanie w dużych i średnich projektach w małych jest to niepotrzebne komplikowanie. Te wzorca podobnie jak większość wzorców mają na celu łatwiejsze późniejsze modyfikowanie projektu, żeby był czysty, elastyczny oraz łatwy do odczytania przez każdego.

 

Cel

  • Zdefiniowanie rodziny algorytmów, hermetyzacja tych algorytmów i użycie ich w zależności od sytuacji.
  • Zahermetyzowanie szczegółów implementacji w klasach pochodnych.

 

Problem

Załóżmy, że masz zrobić projekt zapisywania plików w różnych formatach ,png .txt .csv .jpg etc. doskonały do tego będzie wzorzec Strategy, który rozdzieli algorytmy wykonujące zapisywanie plików w różnych formatach oraz zahermetyzuje te algorytmy do łatwiejszego utrzymania tych algorytmów w przyszłości.

 

Użyj wtedy kiedy:

  • Masz dużo algorytmów poplątanych ze sobą wykonujących różnie funkcje wtedy lepiej upoprządkować je, rozdzielić i zahermetyzować.

 

Struktura

Jak zwykle diagram wzorca Strategia(Strategy).

Wiadomo w sekcji Dyskusja było już wytłumaczone co te klasy robią 🙂 Klasy ImplementationOne i ImplementationTwo to są klasy konkretne ConcreteStrategy dziedziczące po interfejsie Interface.

I tak jak we wzorcu State, klient operuje klasami konkretnymi tylko z poziomu klasy Context.

 

Przykład

Schemat wzorca Strategy w kodzie

Zobaczmy teraz jak wygląda wzorzec Strategy w kodzie.

Zacznijmy od klasy Context.

Jak widać klasa wygląda bardzo podobnie jak klasa Context ze wzorca State. Jak będziemy chcieli używać innego algorytmu będziemy musieli przekazać jego obiekt tutaj.

Teraz interfejs Interface.

I klasy konkretne dziedziczące po interfejsie Interface.

Klasa ImplementationOne.

Oraz klasa ImplementationTwo.

I na końcu klient.

Można zauważyć, że cała struktura jest bardzo podobna do wzorca State, różnią się one tylko celem użycia.

Wynik:

 

Przykład z życia wzięty

Sposób transportu do lotniska

Załóżmy, że mamy zrobić system w którym klient będzie mógł decydować czym chce pojechać do lotniska, wiadomo za różne sposoby transportu będą odpowiadać różne algorytmy, więc dobre będzie tutaj użycie wzorca Strategy, zobaczmy obrazek poniżej, żeby pokazać jak to wygląda.

Zacznijmy w kolejności tak jak w poprzednim przykładzie.

Czyli najpierw klasa Context, w naszym przypadku będzie się ona nazywać TransportToAirport.

Interfejs Interface w naszym przypadku będzie to klasa abstrakcyjna StrategyOfTransport.

Klasy konkretne dziedziczące po klasie StrategyOfTransport.

Czyli Car.

CityBus.

Oraz Taxi.

I na końcu klient.

Wynik:

I mamy następnego klienta 🙂

 

Powiązania z innymi wzorcami

  • Implementacja wzorca Strategia(Strategy) jest bardzo podobna do wzorca Stan(State), te wzorce różnią się jedynie celem użycia.
  • Obiekty wzorca Strategia(Strategy) często wykorzystują wzorzec Pyłek(Flyweight).
  • Wzorce Strategia(Strategy), Stan(State), Most(Bridge) i w pewnym stopniu Adapter(Adapter) mają podobne struktury, czyli głowa(klient albo uchwyt) i ciało, różnią się jedynie celem, wszystkie są do różnych problemów
  • Wzorzec Strategia(Strategy) pozwala zmienić wnętrzności obiektu a Dekorator(Decorator) jego skórkę.

 

Podsumowanie

I to wszystko na temat wzorca Strategia(Strategy)🙂

Link do githuba ze wszystkimi przykładami:  https://github.com/Slaw145/Strategy

To na tyle, jeśli chodzi o wzorce projektowe 🙂 Może jeszcze później będzie dodatkowy krótszy wpis na temat Null Object. Następne omawiane tematy będą prawdopodobnie rozwijać temat Dependency Injection oraz o testów jednostkowych 🙂 później możliwe, że będzie o CQRS, ale jeszcze zobaczymy 🙂

Standardowo, przypominam o newsletterze, którym wysyłam powiadomienia o nowych wpisach oraz dodatkowe informacje na temat, ogółem mówiąc, świecie IT.

KONIECZNIE dołącz do społeczności DevmanCommunity na fb, części społeczności jest w jednym miejscu 🙂

-strona na fb: Devman.pl-Sławomir Kowalski

-grupa na fb: DevmanCommunity

Pytaj, komentuj pod spodem na końcu wpisu, podziel się nim, oceń go, rób co wolisz🙂

Ilustracje, obrazki oraz diagramy są z: https://sourcemaking.com/design_patterns/strategy

 
Jeśli ten wpis ci się przydał podziel się nim ze swoimi znajomymi :)

Post a comment

1 Comment to "Wzorce projektowe: Strategia(Strategy)"

avatar
  Subscribe  
newest oldest evaluated
Notify about