tl  tr
  Home | Tutorials | Articles | Videos | Products | Tools | Search
Interviews | Open Source | Tag Cloud | Follow Us | Bookmark | Contact   
 Design Patterns > Java Design Patterns > Strategy

Strategy 

Strategy pattern comes under Behavioral design pattern. It define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Behaviour & Advantages

  • Defines a family of interchangeable algorithms
  • Lets the algorithm vary independently from clients that use it.
  • Decouples the algorithm from the client that uses it.
Participants
  • Strategy
    Abstract interface for defining an Algorithm.
  • Concrete Strategy
    An implementation of Strategy.
  • Context
    Context contains Strategy interface referring to one of the Concrete Strategies. It uses this interface to invoke the algorithm defined by a Concrete Strategy.

This example shows a text label which supports various borders around it. Here Text class acts as Context and ITextBorder interface acts as Strategy. Classes NoBorder, StarBorder, HashBorder and SlashBorder acts as Concrete Strategies.

We can see that Text class is initialized with default border strategy NoBorder.

File Name  :  
com/bethecoder/tutorials/dp/strategy/Text.java 
   
package com.bethecoder.tutorials.dp.strategy;

import com.bethecoder.tutorials.dp.strategy.impl.NoBorder;

public class Text {

  private String content;
  private ITextBorder textBorder;
  
  public Text(String content) {
    this.content = content;
    this.textBorder = new NoBorder();
  }
  
  public void display() {
    textBorder.printBorder(getContent());
  }
  
  public String getContent() {
    return content;
  }
  
  public void setContent(String content) {
    this.content = content;
  }
  
  public ITextBorder getTextBorder() {
    return textBorder;
  }
  
  public void setTextBorder(ITextBorder textBorder) {
    this.textBorder = textBorder;
  }
  
}
   

ITextBorder strategy is shown below,

File Name  :  
com/bethecoder/tutorials/dp/strategy/ITextBorder.java 
   
package com.bethecoder.tutorials.dp.strategy;

public interface ITextBorder {

  /**
   * Print border around given text.
   
   @param text
   */
  public void printBorder(String text);
  
}
   

Abstract text border implementation.

File Name  :  
com/bethecoder/tutorials/dp/strategy/impl/AbstractTextBorder.java 
   
package com.bethecoder.tutorials.dp.strategy.impl;

import java.util.Arrays;

import com.bethecoder.tutorials.dp.strategy.ITextBorder;

public abstract class AbstractTextBorder implements ITextBorder {

  /**
   * The border character to be provided by
   * child classes.
   
   @return
   */
  public abstract char getBorderChar();
  
  @Override
  public void printBorder(String text) {
    int textLength = text.length();
    int borderWidth = textLength + 4;
    
    char [] border = new char[borderWidth];
    Arrays.fill(border, getBorderChar());
    String borderLine = new String(border);

    /**
     * Print border.
     */
    System.out.println(borderLine);
    
    System.out.print(getBorderChar() " ")
    System.out.print(text);
    System.out.println(" " + getBorderChar())
    
    System.out.println(borderLine);
  }

}
   

StarBorder Concrete Strategy implementation.

File Name  :  
com/bethecoder/tutorials/dp/strategy/impl/StarBorder.java 
   
package com.bethecoder.tutorials.dp.strategy.impl;

public class StarBorder extends AbstractTextBorder {

  @Override
  public char getBorderChar() {
    return '*';
  }
}
   

HashBorder Concrete Strategy implementation.

File Name  :  
com/bethecoder/tutorials/dp/strategy/impl/HashBorder.java 
   
package com.bethecoder.tutorials.dp.strategy.impl;

public class HashBorder extends AbstractTextBorder {

  @Override
  public char getBorderChar() {
    return '#';
  }
}
   

SlashBorder Concrete Strategy implementation.

File Name  :  
com/bethecoder/tutorials/dp/strategy/impl/SlashBorder.java 
   
package com.bethecoder.tutorials.dp.strategy.impl;

public class SlashBorder extends AbstractTextBorder {

  @Override
  public char getBorderChar() {
    return '/';
  }
}
   

NoBorder Concrete Strategy implementation.

File Name  :  
com/bethecoder/tutorials/dp/strategy/impl/NoBorder.java 
   
package com.bethecoder.tutorials.dp.strategy.impl;

import com.bethecoder.tutorials.dp.strategy.ITextBorder;

public class NoBorder implements ITextBorder {

  @Override
  public void printBorder(String text) {
    System.out.println(text);
  }
}
   

Strategy usage is shown below,

File Name  :  
com/bethecoder/tutorials/dp/strategy/Test.java 
   
package com.bethecoder.tutorials.dp.strategy;

import com.bethecoder.tutorials.dp.strategy.impl.HashBorder;
import com.bethecoder.tutorials.dp.strategy.impl.SlashBorder;
import com.bethecoder.tutorials.dp.strategy.impl.StarBorder;

public class Test {

  /**
   @param args
   */
  public static void main(String[] args) {

    Text text = new Text("www.bethecoder.com");
    text.display();
    
    ITextBorder [] borders = {
        new StarBorder(),
        new SlashBorder(),
        new HashBorder(),
    };
    
    for (int i = ; i < borders.length ; i ++) {
      text.setTextBorder(borders[i]);
      text.display();
    }
  }
}
   

It gives the following output,
www.bethecoder.com
**********************
* www.bethecoder.com *
**********************
//////////////////////
/ www.bethecoder.com /
//////////////////////
######################
# www.bethecoder.com #
######################



 
  


  
bl  br