Design Pattern > Behavioral Design Pattern > Strategy Design Pattern
As per GOF the intent of Strategy Design Pattern is to "Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it."
In Strategy Design Pattern we create number of different classes whose structures are same but differ in behaviour( i.e. same method name with different implementation) and appropriate object is decided at run time.
let's see with an example the benefit of strategy pattern.
Problem :
Suppose you are working on a requirement to filter out the digits/numbers from a given string.Client class would be similer to following
public String filterNumbers(String input) {
// add logic to filter numbers from string
return filteredString;
}
Now, a new requirement come up to filter out the special characters, now client class need to be changed,
public String filterNumbers(String input,String filterType ) {
if(filterType.equals("number"){
// add logic to filter numbers from input string
}
else if(filterType.equals("specialChar"){
// add logic to filter special characters from input string
}
return filteredString;
}
further if more requirements come then you have to change the client code again and again and that's not a good design.
Solution :
Strategy Design Pattern helps in this situation, here we seperate client class with filterlogic.
Key terms in this pattern are :
1. Strategy :
2. Concrete Strategy Class :
3. Context :
4. Client :
Benefit here we got is that we can create different filter strategy and use them in client class without changing the existing design.
Java Implementation :
/**
* Strategy interface
*/
package com.kmingle.strategy;
public interface Strategy {
void doFilter(String input);
}
/**
* Concrete Strategy Class to filter out numbers from input
*/
package com.kmingle.strategy;
public class NumberStrategy implements Strategy {
/* (non-Javadoc)
* @see com.kmingle.strategy.Strategy#doFilter(java.lang.String)
*/
@Override
public void doFilter(String input) {
System.out.println("numbers filtered out from input string");
}
}
/**
* Concrete Strategy Class to filter out special characters from input
*/
package com.kmingle.strategy;
public class SpecialCharStrategy implements Strategy {
/* (non-Javadoc)
* @see com.kmingle.strategy.Strategy#doFilter(java.lang.String)
*/
@Override
public void doFilter(String input) {
System.out.println("special characters filtered out from input string");
}
}
/**
* Context class
*/
package com.kmingle.strategy;
public class Context {
Strategy filterStrategy;
public Context(Strategy strategy){
filterStrategy = strategy;
}
public void doFilter(String input){
filterStrategy.doFilter(input);
}
}
/**
* Client Class
*/
package com.kmingle.strategy;
public class StrategyDemo {
public static void main(String[] args) {
// create context with number filter strategy
Context context = new Context(new NumberStrategy());
// filter out number from input string
context.doFilter("input string 1234 @#$&");
// change same context to refer specialchar filter strategy
context = new Context(new SpecialCharStrategy());
// filter out special characters from input string
context.doFilter("input string 1234 @#$&");
}
}
Output :
numbers filtered out from input string
special characters filtered out from input string
As per GOF the intent of Strategy Design Pattern is to "Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it."
In Strategy Design Pattern we create number of different classes whose structures are same but differ in behaviour( i.e. same method name with different implementation) and appropriate object is decided at run time.
let's see with an example the benefit of strategy pattern.
Problem :
Suppose you are working on a requirement to filter out the digits/numbers from a given string.Client class would be similer to following
public String filterNumbers(String input) {
// add logic to filter numbers from string
return filteredString;
}
Now, a new requirement come up to filter out the special characters, now client class need to be changed,
public String filterNumbers(String input,String filterType ) {
if(filterType.equals("number"){
// add logic to filter numbers from input string
}
else if(filterType.equals("specialChar"){
// add logic to filter special characters from input string
}
return filteredString;
}
further if more requirements come then you have to change the client code again and again and that's not a good design.
Solution :
Strategy Design Pattern helps in this situation, here we seperate client class with filterlogic.
Key terms in this pattern are :
1. Strategy :
- An interface with doFilter method declaraction
2. Concrete Strategy Class :
- Implements Strategy interface with business logic to dofilter
3. Context :
- Class with reference to Strategy interface
- Client code has access to this class methods
- executs business login of Strategy object at runtime
4. Client :
- Create context objects and call dofilter method
Benefit here we got is that we can create different filter strategy and use them in client class without changing the existing design.
Java Implementation :
/**
* Strategy interface
*/
package com.kmingle.strategy;
public interface Strategy {
void doFilter(String input);
}
/**
* Concrete Strategy Class to filter out numbers from input
*/
package com.kmingle.strategy;
public class NumberStrategy implements Strategy {
/* (non-Javadoc)
* @see com.kmingle.strategy.Strategy#doFilter(java.lang.String)
*/
@Override
public void doFilter(String input) {
System.out.println("numbers filtered out from input string");
}
}
/**
* Concrete Strategy Class to filter out special characters from input
*/
package com.kmingle.strategy;
public class SpecialCharStrategy implements Strategy {
/* (non-Javadoc)
* @see com.kmingle.strategy.Strategy#doFilter(java.lang.String)
*/
@Override
public void doFilter(String input) {
System.out.println("special characters filtered out from input string");
}
}
/**
* Context class
*/
package com.kmingle.strategy;
public class Context {
Strategy filterStrategy;
public Context(Strategy strategy){
filterStrategy = strategy;
}
public void doFilter(String input){
filterStrategy.doFilter(input);
}
}
/**
* Client Class
*/
package com.kmingle.strategy;
public class StrategyDemo {
public static void main(String[] args) {
// create context with number filter strategy
Context context = new Context(new NumberStrategy());
// filter out number from input string
context.doFilter("input string 1234 @#$&");
// change same context to refer specialchar filter strategy
context = new Context(new SpecialCharStrategy());
// filter out special characters from input string
context.doFilter("input string 1234 @#$&");
}
}
Output :
numbers filtered out from input string
special characters filtered out from input string
No comments:
Post a Comment