Strategia (Strategy)
Stosujemy wtedy gdy mamy możliwość wyboru kilku algorytmów wykonania różniących
się właściwościami. Programista wybiera strategie, która będzie dla
niego optymalna do wykonania.
Innymi słowy strategia definiuje rodzinę wymiennych algorytmów
i kapsułkuje je w postaci klas. Umożliwia wymienne stosowanie
każdego z nich w trakcie działania aplikacji niezależnie
od korzystających z nich klientów.
Wzorzec ten jest podobny do wzorca metody szablonowej. Przedstawie różnice jakie
występują pomiędzy tymi dwoma wzorcami po przeanalizowaniu pierwszego przykładu.
Czas na przykład.
1. Na początek zostaje zdefiniowany interfejs strategii
wraz z metodą solve(). Oczywiście nazwa metody może
być dowolna.
interface Strategy { public void solve(); }
2. W strategii podobnie jak w metodzie szablonowej istnieje jedna metoda solve(),
jednak różnica polega na tym, iż w przypadku strategii metodę tą możemy
redefiniować. W strategii metody są różne i metoda solve() może być różnie
zaimplementowana.
abstract class TemplateMethod1 implements Strategy { public void solve() { start(); while (nextTry() && ! isSolution()) ; stop(); } protected abstract void start(); protected abstract boolean nextTry(); protected abstract boolean isSolution(); protected abstract void stop(); }
3. Tworzymy teraz konkretną implementacje klasy TemplateMethod1.
Z tego wynika, iż należy zdefiniować odpowiednio metody:
start();
nextTry();
isSolution();
stop();
class Impl1 extends TemplateMethod1 { private int state = 1; protected void start() { System.out.print( "start " ); } protected void stop() { System.out.println( "stop" ); } protected boolean nextTry() { System.out.print( "nextTry-" + state++ + " " ); return true; } protected boolean isSolution() { System.out.print( "isSolution-" + (state == 3) + " " ); return (state == 3); } }
4. Nowa/inna klasa abstrakcyjna, która jest analogiczna do klasy
TemplateMethod1. Prosze zwrócić uwagę jakie teraz klasa zawiera
metody oraz jak została zaimplementowana metoda solve().
Na tym właśnie polega różnica, co do wzorca metody szablonowej.
abstract class TemplateMethod2 implements Strategy { public void solve() { while (true) { preProcess(); if (search()) break; postProcess(); } } protected abstract void preProcess(); protected abstract boolean search(); protected abstract void postProcess(); }
5. Analogiczna sytuacja do klasy Impl1.
Tworzymy teraz konkretną implementacje klasy TemplateMethod2.
Należy teraz odpowiednio zdefiniować metody:
preProcess();
search();
postProcess();
class Impl2 extends TemplateMethod2 { private int state = 1; protected void preProcess() { System.out.print( "preProcess " ); } protected void postProcess() { System.out.print( "postProcess " ); } protected boolean search() { System.out.print( "search-" + state++ + " " ); return state == 3 ? true : false; } }
6. Na zakończenie krótki test naszych klas.
public class StrategyDemo { public static void clientCode( Strategy strat ) { strat.solve(); } public static void main( String[] args ) { Strategy[] algorithms = { new Impl1(), new Impl2() }; for (int i=0; i < algorithms.length; i++) { clientCode( algorithms[i] ); } } }
Zachecam do przeczytania wpisu o metodzie szablonowej. Dzięki temu
będzie można łatwo rozróżnić różnice pomiędzy strategią, a metodą
szablonową.
Diagram klas:
Brak komentarzy:
Prześlij komentarz