Monday, February 28, 2011

Strategy pattern

The Strategy Design Pattern basically consists of decoupling an algorithm from its host, and encapsulating the algorithm into a separate class. More simply put, an object and its behaviour are separated and put into two different classes. This allows you to switch the algorithm that you are using at any time.

There are several advantages to doing this. First, if you have several different behaviours that you want an object to perform, it is much simpler to keep track of them if each behaviour is a separate class, and not buried in the body of some method. Should you ever want to add, remove, or change any of the behaviours, it is a much simpler task, since each one is its own class. Each such behaviour or algorithm encapsulated into its own class is called a Strategy.

When you have several objects that are basically the same, and differ only in their behaviour, it is a good idea to make use of the Strategy Pattern.. Using Strategies, you can reduce these several objects to one class that uses several Strategies. The use of strategies also provides a nice alternative to subclassing an object to achieve different behaviours. When you subclass an object to change its behaviour, that behaviour that it executes is static. If you wanted to change what it does, you'd have to create a new instance of a different subclass and replace that object with it. With Strategies, however, all you need to do is switch the object's strategy, and it will immediately change how it behaves. Using Strategies also eliminates the need for many conditional statements. When you have several behaviours together in one class, it is difficult to choose among them without resorting to conditional statements. If you use Strategies you won't need to check for anything, since whatever the current strategy is just executes without asking questions.

strategy_implementation_-_uml_class_diagram

So context has strategy reference and it changes it strategy whenever needed, by using it setters for that strategy reference.

Example

Strategy.java
Suppose we are into making cake, and there are few strategies of making cake.

package com.cakes;

public interface Strategy {

boolean checkTemperature(int temperatureInF);

}


Strategy1


The HikeStrategy class is a concrete strategy class that implements the Strategy interface. The checkTemperature method is implemented so that if the temperature is between 50 and 90, it returns true. Otherwise it returns false.

HikeStrategy.java

package com.cakes;

public class HikeStrategy implements Strategy {

@Override
public boolean checkTemperature(int temperatureInF) {
if ((temperatureInF >= 50) && (temperatureInF <= 90)) {
return true;
} else {
return false;
}
}

}



Strategy 2 :


The SkiStrategy implements the Strategy interface. If the temperature is 32 or less, the checkTemperature method returns true. Otherwise it returns false.

SkiStrategy.java

package com.cakes;

public class SkiStrategy implements Strategy {

@Override
public boolean checkTemperature(int temperatureInF) {
if (temperatureInF <= 32) {
return true;
} else {
return false;
}
}

}



Context


The Context class contains a temperature and a reference to a Strategy. The Strategy can be changed, resulting in different behavior that operates on the same data in the Context. The result of this can be obtained from the Context via the getResult() method.

package com.cakes;

public class Context {

int temperatureInF;
Strategy strategy;

public Context(int temperatureInF, Strategy strategy) {
this.temperatureInF = temperatureInF;
this.strategy = strategy;
}

public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}

public int getTemperatureInF() {
return temperatureInF;
}

public boolean getResult() {
return strategy.checkTemperature(temperatureInF);
}

}


Demo of pattern


The Demo class creates a Context object with a temperature of 60 and with a SkiStrategy. It displays the temperature from the context and whether that temperature is OK for skiing. After that, it sets the Strategy in the Context to HikeStrategy. It then displays the temperature from the context and whether that temperature is OK for hiking.


Demo.java

package com.cakes;

public class Demo {

public static void main(String[] args) {

int temperatureInF = 60;

Strategy skiStrategy = new SkiStrategy();
Context context = new Context(temperatureInF, skiStrategy);

System.out.println("Is the temperature (" + context.getTemperatureInF() + "F) good for skiing? " + context.getResult());

Strategy hikeStrategy = new HikeStrategy();
context.setStrategy(hikeStrategy);

System.out.println("Is the temperature (" + context.getTemperatureInF() + "F) good for hiking? " + context.getResult());

}

}



Console Output
Is the temperature (60F) good for skiing? false
Is the temperature (60F) good for hiking? true

No comments:

Post a Comment

Chitika