sobota, 1 marca 2014

Strategia (obiektowy)

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