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.
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,
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.
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.
package com.bethecoder.tutorials.dp.strategy.impl;
public class StarBorder extends AbstractTextBorder {
@Override
public char getBorderChar () {
return '*' ;
}
}
HashBorder Concrete Strategy implementation.
package com.bethecoder.tutorials.dp.strategy.impl;
public class HashBorder extends AbstractTextBorder {
@Override
public char getBorderChar () {
return '#' ;
}
}
SlashBorder Concrete Strategy implementation.
package com.bethecoder.tutorials.dp.strategy.impl;
public class SlashBorder extends AbstractTextBorder {
@Override
public char getBorderChar () {
return '/' ;
}
}
NoBorder Concrete Strategy implementation.
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,
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 = 0 ; 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 #
######################