Polub bloga na fejsie!

Wzorzec Strategia w JavaScript

0

Postem tym chciałbym rozpocząć mini cykl o zastosowaniu wzorców projektowych w języku JavaScript –  wbrew pozorom, w tym języku również można je stosować! Na pierwszy ogień przedstawię dziś wzorzec Strategia w JavaScript. Myślę, że większość z nas, stosowała i stosuje ten wzorzec na co dzień (czasem nawet nieświadomie), jednak dla przypomnienia (za wikipedią):

Wzorzec strategii definiuje rodzinę algorytmów, z których każdy zdefiniowany jest w osobnej klasie implementującej wspólny interfejs – dzięki temu możliwe jest wymienne stosowanie każdego z tych algorytmów, nie będąc zależnymi od klas klienckich.

Przykład – HTML

To tyle tytułem wstępu – zakładam, że implementacja tego wzorca w języku takim jak np. C# jest znana, chciałbym się więc skupić na tym jak skorzystać z niego JavaScript. Dla osób, które nie miały dotąd styczności z OOP w JavaScript, proponuje wcześniejsze zapoznanie się z tą tematyką. Można zacząć na przykład od stron mozilli dla developerów. Przejdźmy zatem do przykładu – załóżmy taki oto kod html:

Mamy tutaj trzy radiobuttony, przycisk ‚Wyświetl’ oraz paragraf. Radiobuttony odpowiadają opcjom ‚Błąd’, ‚Ostrzeżenie’ oraz ‚Informacja’ – po wybraniu jednego z nich i naciśnięciu przycisku ‚Wyświetl’, wewnątrz tag’u <p>, zamiast wartości ‚—‚ ma się pojawić odpowiednia informacja (dodatkowo w zależności czy będzie to błąd, ostrzeżenie czy informacja, tekst powinien być odpowiednio „ostylowany”).

Obsługa zadania

Do obsługi takiego zadania moglibyśmy użyć takiego kodu JavaScript:

Jak widać, w „on document ready” (jQuery) mamy inicjalizację obsługi zdarzenia ‚change’ dla wszystkich radiobuttonów na stronie. Funkcja obsługująca zdarzenie pobiera wartość atrybutu ‚value’ radiobuttona, który został w danym momencie kliknięty – w zależności od tej wartości, definiowana jest funkcja obsługująca zdarzenie ‚click’ przycisku (tego, który wyświetlać ma komunikat). W powyższym przykładzie, zastosowana została instrukcja warunkowa switch, a każdy z obsługiwanych przypadków jest bardzo podobny – mamy funkcję obsługującą zdarzenie ‚click’, a w niej, z pomocą metod jQuery, odpowiednie „ostylowanie” elementu <p> i nadanie odpowiedniego tekstu.

Myślę, że w takim przypadku, aż się prosi o zastosowanie wzorca strategii… W naszym przypadku, utworzymy klasę abstrakcyjną zawierającą deklarację metody show(), która odpowiedzialna będzie za odpowiednie „ostylowanie” naszego elementu <p> – odpowiednia implementacja tej metody będzie wywoływana w funkcji obsługującej zdarzenie click buttona ‚Wyświetl’.

Implementacja strategii

Zacznijmy więc przykład implementacji strategii, na początek klasa bazowa:

Mamy tutaj definicję klasy Message, z konstruktorem bez parametrów (function() nie przyjmuje żadnych parametrów). Ponadto definiujemy metodę show(), która rzuca wyjątkiem jeśli próbowalibyśmy użyć jej bezpośrednio (czyli jest to metoda bardziej wirtualna niż abstrakcyjna – w JavaScript nie mamy takiego rozróżnienia, liczy się efekt jaki w ten sposób osiągamy – jeśli w klasie dziedziczącej po Message nie zaimplementujemy metody show(), rzucony zostanie wyjątek).

Klasy dziedziczące po Message

Kolejna rzecz, to implementacja poszczególnych klas strategii dziedziczących po Message. Poniżej jedna z takich klas:

Na powyższym przykładzie, widać w jaki sposób realizowane jest dziedziczenie w JavaScript – w pierwszej linijce mamy deklarację klasy ErrorMessage za pomocą konstruktora bezparametrowego. W kolejnej linii informujemy, że klasa ErrorMessage dziedziczy z Message (klasa Message jest prototypem dla ErrorMessage). Kolejne linijki to już konkretna implementacja/przesłonięcie metody show(). Poniżej pozostałe strategie:

Wykorzystanie strategii w praktyce

Wzorzec strategii, w codziennym zastosowaniu bardzo często występuje w połączeniu z wzorcem fabryki – np. klasy ze statycznymi metodami zwracającymi odpowiednie implementacje algorytmu. W naszym przypadku zrobimy coś podobnego – zdefiniujemy obiekt, z właściwościami, których nazwy odpowiadać będą wartościom (atrybuty ‚value’) poszczególnych radiobuttonów, a wartości przypisanym im strategiom:

Pozostało nam już tylko wykorzystanie tak utworzonych strategii w praktyce:

Tak jak w przykładzie na początku artykułu, mamy obsługę zdarzenia ‚change’ radiobuttonów, z tą różnicą, że zamiast instrukcji warunkowej ‚switch’ wykorzystujemy utworzone wcześniej strategie – jak widać w linii nr 3, na podstawie wartości aktualnie zaznaczonego radiobuttona, z obiektu messages, pobierana jest odpowiednia klasa strategii. Następnie metoda show() tej klasy, wykorzystywana jest do obsługi zdarzenia ‚click’ przycisku ‚Wyświetl’.

W ten sposób uniezależniliśmy wyświetlanie komunikatów od funkcji obsługującej zdarzenie ‚click’ – jeśli chcemy dokonać zmian w sposobie wyświetlania, robimy to w odpowiednich klasach strategii. Możemy również napisać nowe strategie wyświetlania komunikatów i podmienić je – wszystkie korzyści płynące z wzorca strategia są dostępne.

Wzorzec strategia w JavaScript – podsumowanie

To w zasadzie wszystko, jak widać skorzystanie z benefitów wzorców projektowych jest możliwe również w języku JavaScript. Mam nadzieję, że teraz wzorzec strategia w JavaScript nie będzie już dla Ciebie tajemnicą… W przyszłości postaram się pokazać również implementację innych wzorców, znanych nam z typowych języków obiektowych.

W pełni działający opisany powyżej dostępny jest do przetestowania w jsfiddle.

REACT, REDUX, REACT-ROUTER - KURSY ON-LINE

Chcesz od podstaw poznać tajniki React, Redux oraz react-router? Zapraszam do moich szkoleń on-line:

Przejdź do szkoleń
Google Analytics Alternative