Strategy design pattern defines a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. In computer programming, the strategy pattern is also known as the policy pattern.

Situations of using Strategy Pattern

Use the Strategy pattern when

  • You need different variants of an algorithm
  • An algorithm uses data that clients shouldn’t know about
  • A class defines many behaviors, and these appear as multiple switch statement in the classes operations
  • Many related classes differ only in their behavior

Examples

Different types of sorts have different characteristics

Shellsort

  • No extra space needed
  • Fast but not O(n*log(n))
  • Very fast on nearly sorted data
  • Does comparatively well on small lists

Quicksort

  • Average case is O(n*log(n))
  • Relatively poor performance on short lists
  • Requires a stack of ~ log(n) in depth

MergeSort

  • Worst case is O(n*log(n))
  • Requires O(n) extra space
  • Stable

Now you have a sortedList container. You can use any of above mentioned algorithms to sort items in that container. But you can use only one algorithm at a time out of all the possible. For example

SortedList studentRecords = new SortedList( new ShellSort() ); 
studentRecords.add( "Sam" );

Solution

First you need to define the Strategy and Context interfaces. Context pass data to Strategy. Strategy has point to Context that gets data from Context. Strategies can be used as template parameters if strategy can be selected at compile-time and does not change at run-time.

Strategy Implementation using Java

A simplified graphing program that can present data as a line graph or a bar chart. Since each plot will appear in its own frame, our base PlotStrategy class will be derived from JFrame:

Plot Strategy Class:

public abstract class PlotStrategy extends JFrame {
   protected float[] x, y;
   protected Color color;
   protected int width, height;
   public PlotStrategy(String title) {
      super(title);
      width = 300; height =200;
      color = Color.black;
      addWindowListener(new WindAp(this));
   }
//--------------------------------------
public abstract void plot(float xp[], float yp[]);
//--------------------------------------
public void setPenColor(Color c) {
color = c;
}
class WindAp extends WindowAdapter {
   JFrame fr;
   public WindAp(JFrame f) {
      fr = f; //copy Jframe instance
   }
   public void WindowClosing(WindowEvent e) {
      fr.setVisible(false); //hide window
   }
}

The Context class:

The Context class is the traffic cop that decides which strategy is to be called. The decision is usually based on a request from the client program. All that the Context needs to do is to set a variable to refer to one concrete strategy or another.

public class Context {
   //this object selects one of the strategies to be used for plotting
   //the plotStrategy variable points to selected strategy
   private PlotStrategy plotStrategy;
   float x[], y[]; //data stored here
   //---------------------------------
   public Context() {
      setLinePlot(); //make sure it is not null
   }
   //---------------------------------
   //make current strategy the Bar Plot
   public void setBarPlot() { plotStrategy = new BarPlotStrategy(); }
   //---------------------------------
   //make current strategy the Line Plot
   public void setLinePlot() { plotStrategy = new LinePlotStrategy(); }
   //---------------------------------
   //call plot method of current strategy
   public void plot() {
      plotStrategy.plot(x, y);
   }
   //---------------------------------
   public void setPenColor(Color c) {
      plotStrategy.setPenColor(c);
   }
   //---------------------------------
   public void readData(String filename) {
      //read data from datafile somehow
   }
}

Test Program

This simple program is just a panel with two buttons that call the two plots:

Line Graph Button class:

public class JGraphButton extends JButton implements Command {
   Context context;
   public JGraphButton(ActionListener act, Context ctx) {
      super("Line graph"); //button label
      addActionListener(act); //add listener
      context = ctx; //copy context
   }
   //-------------------------------
   public void Execute() {
      context.setPenColor(Color.red); //set color of plot
      context.setLinePlot(); //set kind of plot
      context.readData("data.txt"); //read the data
      context.plot(); //plot the data
   }
}

The two strategy classes are pretty much the same: they set up the window size for plotting call a plot method specific for that display panel.

Line graph Strategy class:

public class LinePlotStrategy extends PlotStrategy {
   LinePlotPanel lp;
   public LinePlotStrategy() {
      super("Line plot");
      lp = new LinePlotPanel();
      getContentPane().add(lp);
   }
   public void plot(float[] xp, float[] yp) {
      x = xp; y = yp; //copy in data
      findBounds(); //sets maxes and mins
      setSize(width, height);
      setVisible(true);
      setBackground(Color.white);
      lp.setBounds(minX, minY, maxX, maxY);
      lp.plot(xp, yp, color); //set up plot data
      repaint(); //call paint to plot
   }
}

We create a PlotPanel class based on JPanel and derive two classes from it for the actual line and bar plots:

PlotPanel (Base class):

public class PlotPanel extends JPanel {
   float xfactor, yfactor;
   int xpmin, ypmin, xpmax, ypmax;
   float minX, maxX, minY, maxY;
   float x[], y[];
   Color color;
   //--------------------------------------------
   public void setBounds(float minx, float miny,
                                       float maxx, float maxy) {
      minX=minx; maxX= maxx;
      minY=miny; maxY = maxy;
   }
   //--------------------------------------------
   public void plot(float[] xp, float[] yp, Color c) {
      x = xp; //copy in the arrays
      y = yp;
      color = c; //and color
      //compute bounds and sclaing factors
      int w = getWidth() - getInsets().left - getInsets().right;
      int h = getHeight() - getInsets().top - getInsets().bottom;
      xfactor = (0.9f * w) / (maxX - minX);
      yfactor = (0.9f * h)/ (maxY - minY);
      xpmin = (int)(0.05f * w); ypmin = (int)(0.05f * h);
      xpmax = w - xpmin; ypmax = h - ypmin;
      repaint(); //this causes the actual plot
   }
   //--------------------------------------
   protected int calcx(float xp) {
      return (int)((xp-minX) * xfactor + xpmin);
   }
   protected int calcy(float yp) {
      int ypnt = (int)((yp-minY) * yfactor);
      return ypmax - ypnt;
   }
}

LinePlotPanel (Derived classe): 

public class LinePlotPanel extends PlotPanel {
   public void paint(Graphics g) {
      int xp = calcx(x[0]); //get first point
      int yp = calcy(y[0]);
      g.setColor(Color.white); //flood background
      g.fillRect(0,0,getWidth(), getHeight());
      g.setColor(Color.black);
      //draw bounding rectangle
      g.drawRect(xpmin, ypmin, xpmax, ypmax);
      g.setColor(color);
      //draw line graph
      for(int i=1; i< x.length; i++) {
         int xp1 = calcx(x[i]); //get n+1st point
         int yp1 = calcy(y[i]);
         g.drawLine(xp, yp, xp1, yp1); //draw line
         xp = xp1; //copy for next loop
         yp = yp1;
      }
   }
}

Consequences

  • Families of related algorithms Alternative to subclassing of Context. What is the big deal? You still subclass Strategy!
  • Gives a choice of implementations
  • Clients must be aware of different Strategies
  • Communication overhead between Strategy and Context
  • Increase number of objects
  • Eliminates conditional statements. Replace in Context code like:
         switch ( flag ) {
           case A:  
                  doA();
                  break;
         case B:  
                  doB();
                  break;
         case C: 
                  doC();
                  break;
         }

With code like:

        strategy.do();
Tagged with: Design PatternJAVAObject Oriented
 

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

Looking for something?

Use the form below to search the site:


Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Related News Feeds

Set your Twitter account name in your settings to use the TwitterBar Section.