Definition
Group several algorithms in a single module to provide alternatives. Also known as policy.Where to use & benefits
- Encapsulate various algorithms to do more or less the same thing.
- Need one of several algorithms dynamically.
- The algorithms are exchangeable and vary independently
- Configure a class with one of many related classes (behaviors).
- Avoid exposing complex and algorithm-specific structures.
- Data is transparent to the clients.
- Reduce multiple conditional statements.
- Provide an alternative to subclassing.
- Related patterns include
- State, which can activate several states, whereas a strategy can only activate one of the algorithms.
- Flyweight, which provides a shared object that can be used in multiple contexts simultaneously, whereas a strategy focuses on one context.
- Decorator, which changes the skin of an object, whereas a strategy changes the guts of an object.
- Composite, which is used to combine with a strategy to improve efficiency.
Motivation
There are common situations when classes differ only in their behavior. For this cases is a good idea to isolate the algorithms in separate classes in order to have the ability to select different algorithms at runtime.
Intent
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Implementation
Strategy - defines an interface common to all supported algorithms. Context uses this interface to call the algorithm defined by a ConcreteStrategy.
ConcreteStrategy - each concrete strategy implements an algorithm.
Context - contains a reference to a strategy object.
- may define an interface that lets strategy accessing its data.
The context object receives requests from the client and delegates them to the strategy object. Usually the ConcreteStartegy is created by the client and passed to the context. From this point the clients interacts only with the context.
Intent
01- Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.
- Capture the abstraction in an interface, bury implementation details in derived classes.
Problem
02One of the dominant strategies of object-oriented design is the “open-closed principle”.
03Figure demonstrates how this is routinely achieved - encapsulate interface details in a base class, and bury implementation details in derived classes. Clients can then couple themselves to an interface, and not have to experience the upheaval associated with change: no impact when the number of derived classes changes, and no impact when the implementation of a derived class changes.
A generic value of the software community for years has been, “maximize cohesion and minimize coupling”. The object-oriented design approach shown in figure is all about minimizing coupling. Since the client is coupled only to an abstraction (i.e. a useful fiction), and not a particular realization of that abstraction, the client could be said to be practicing “abstract coupling” . an object-oriented variant of the more generic exhortation “minimize coupling”.
05A more popular characterization of this “abstract coupling” principle is “Program to an interface, not an implementation”.
06Clients should prefer the “additional level of indirection” that an interface (or an abstract base class) affords. The interface captures the abstraction (i.e. the “useful fiction”) the client wants to exercise, and the implementations of that interface are effectively hidden.
Structure
07The Interface entity could represent either an abstract base class, or the method signature expectations by the client. In the former case, the inheritance hierarchy represents dynamic polymorphism. In the latter case, the Interface entity represents template code in the client and the inheritance hierarchy represents static polymorphism.
Example
08A Strategy defines a set of algorithms that can be used interchangeably. Modes of transportation to an airport is an example of a Strategy. Several options exist such as driving one’s own car, taking a taxi, an airport shuttle, a city bus, or a limousine service. For some airports, subways and helicopters are also available as a mode of transportation to the airport. Any of these modes of transportation will get a traveler to the airport, and they can be used interchangeably. The traveler must chose the Strategy based on tradeoffs between cost, convenience, and time.
Strategy design pattern
01- Define the interface of an interchangeable family of algorithms
- Bury algorithm implementation details in derived classes
- Derived classes could be implemented using the Template Method pattern
- Clients of the algorithm couple themselves strictly to the interface
// 1. Define the interface of the algorithm
interface Strategy { public void solve(); }
// 2. Bury implementation
abstract class TemplateMethod1 implements Strategy { // 3. Template Method
public void solve() {
start();
while (nextTry() && ! isSolution())
;
stop();
}
protected abstract void start();
protected abstract boolean nextTry();
protected abstract boolean isSolution();
protected abstract void stop();
}
class Impl1 extends TemplateMethod1 {
private int state = 1;
protected void start() {
System.out.print( "start " );
}
protected void stop() {
System.out.println( "stop" );
}
protected boolean nextTry() {
System.out.print( "nextTry-" + state++ + " " );
return true;
}
protected boolean isSolution() {
System.out.print( "isSolution-" + (state == 3) + " " );
return (state == 3);
}
}
// 2. Bury implementation
abstract class TemplateMethod2 implements Strategy { // 3. Template Method
public void solve() {
while (true) {
preProcess();
if (search()) break;
postProcess();
}
}
protected abstract void preProcess();
protected abstract boolean search();
protected abstract void postProcess();
}
class Impl2 extends TemplateMethod2 {
private int state = 1;
protected void preProcess() { System.out.print( "preProcess " ); }
protected void postProcess() { System.out.print( "postProcess " ); }
protected boolean search() {
System.out.print( "search-" + state++ + " " );
return state == 3 ? true : false;
}
}
// 4. Clients couple strictly to the interface
public class StrategyDemo {
public static void clientCode( Strategy strat ) {
strat.solve();
}
public static void main( String[] args ) {
Strategy[] algorithms = { new Impl1(), new Impl2() };
for (int i=0; i < algorithms.length; i++) {
clientCode( algorithms[i] );
}
}
}
start nextTry-1 isSolution-false nextTry-2 isSolution-true stop preProcess search-1 postProcess preProcess search-2
No comments:
Post a Comment