Computer Science Design Patterns/Strategy

{{Computer Science Design Patterns/Page
 * mode={{{mode|reading}}}
 * page={{{page|{{SUBPAGENAME}}}}}
 * stage=25
 * stage date=4 Mar, 2014
 * stage comment=Add more illustrations.
 * previous=State
 * next=Template method
 * content=

Scope
Object

Purpose
Behavioral

Intent
Define a family of algorithms, encapsulate each one, and make them interchangeable to let clients and algorithms vary independently from the clients using it.

Applicability

 * when an object should be configurable with one of several algorithms,
 * and all algorithms can be encapsulated,
 * and one interface covers all encapsulations

Consequences

 * + greater flexibility, reuse
 * + can change algorithms dynamically
 * - strategy creation & communication overhead
 * - inflexible Strategy interface

Implementation

 * exchanging information between a Strategy and its context
 * static strategy selection via templates

Related patterns

 * State, can activate several states, whereas a strategy can only activate one of the algorithms.
 * Flyweight, provides a shared object that can be used in multiple contexts simultaneously, whereas a strategy focuses on one context.
 * Decorator, changes the skin of an object, whereas a strategy changes the guts of an object.
 * Composite, is used in combination with a strategy to improve efficiency.

Description
Suppose that you work for a company that builds a strategy game. Let's assume that you've come up with the following hierarchy of classes. All characters are able to walk, and there is also a method to render them on screen. The superclass takes care of the implementation of  method, while each subclass provides its own implementation of   since each character looks different.

A new requirement arrives that the characters need to fight, too. Simple job you say; just add a  method to   superclass. But, wait a moment; what about Workers? They cannot fight!



Well, one could think that you could simply override  method in   subclass to just do nothing. But what if in the future there is a need for a  class that can fight but shouldn’t walk? We need a cleaner solution. What about taking out the fight and walk behaviors from the superclass to an interface? That way, only the characters that are supposed to walk should implement the Walkable interface and only those characters that are supposed to fight should implement the  interface.



Well, this is another way to say for duplicate code. What if you need to make a small change to the fight behavior? You would need to modify all the classes. At this point we should put down three design principles to follow in our application development: So, let's apply the 1st design principle. Pull out fight and walk behavior to different classes. And to apply the 2nd design principle as well, we have to pull out these behaviors to interfaces. Hence, we create a new WeaponBehavior interface to deal with fight behavior, and similarly a WalkBehavior interface to deal with walk behavior.
 * 1) Identify the aspects of your application that vary and separate them from what stays the same. Take what varies and “encapsulate” it so it won’t affect the rest of your code.
 * 2) Program to an interface not to an implementation.
 * 3) Favour composition over inheritance.



s’ behaviors live in separate classes that implement a particular behavior interface. That way, the  classes don’t need to know any of the implementation details for their own behaviors. In addition, we no more rely on an implementation but on an interface. Other types of objects can use these behaviors, too, because they're not hidden inside our  class. And we can add new behaviors without modifying any of the existing ones or touching our character classes. So now, all we have to do is have our  class delegate all behavior information to the two behavior interfaces (so here comes the 3rd design principle). We do that by adding two instance variables to,   and.

Each character object will set these variables polymorphically to reference the specific behavior type it would like at runtime. Think of these behaviors as families of algorithms. So, composition gives you a lot of flexibility. Not only does it let you encapsulate a family of algorithms into their own set of classes, but it also lets you change behavior at runtime as long as the object you are composing with, implements the correct behavior interface.

Cost
Think twice before implementing this pattern. You have to be sure your need is to frequently change an algorithm. You have to clearly anticipate the future, otherwise, this pattern will be more expensive than a basic implementation.

Creation
This pattern is expensive to create.

Maintenance
This pattern can be expensive to maintain. If the representation of a class often changes, you will have lots of refactoring.

Removal
This pattern is hard to remove too.

Advises

 * Use the strategy term to indicate the use of the pattern to the other developers.

Implementations
The strategy pattern in ActionScript 3:

A struct in C can be used to define a class, and the strategy can be set using a function pointer. The following mirrors the Python example, and uses C99 features:

The strategy pattern in C++ is similar to Java, but does not require dynamic allocation of objects.

Another Example:

Delegates in C# follow the strategy pattern, where the delegate definition defines the strategy interface and the delegate instance represents the concrete  strategy. .NET 3.5 defines the Func<,> delegate which can be used to quickly implement the strategy pattern as shown in the example below. Note the 3 different methods for defining a delegate instance.

Using interfaces
An example in Common Lisp: Using strategy classes:

In Common Lisp using first class functions:

Similar to Python and Scala, Falcon supports first-class functions. The following implements the basic functionality seen in the Python example.

Fortran 2003 adds procedure pointers, abstract interfaces and also first-class functions. The following mirrors the Python example.

This Groovy example is a basic port of the Ruby using blocks example. In place of Ruby's blocks, the example uses Groovy's closure support.

An example in Java:

An example in Java:

Similar to Python and Scala, JavaScript supports first-class functions. The following implements the basic functionality seen in the Python example.

Perl has first-class functions, so as with Python, JavaScript and Scala, this pattern can be implemented without defining explicit subclasses and interfaces:

The strategy pattern can be formally implemented with Moose:

The strategy pattern in PHP:

PowerShell has first-class functions called ScriptBlocks, so the pattern can be modeled like Python, passing the function directly to the context instead of defining a class.

An alternative to using New-Module

The following example is equivalent to the C# example 1 above, but in Python.

Second example in Python:

Another example in Python: Python has first-class functions, so the pattern can be used simply by passing the function directly to the context instead of defining a class with a method containing the function. One loses information because the interface of the strategy is not made explicit, however, by simplifying the pattern in this manner.

Here's an example you might encounter in GUI programming, using a callback function:

An example in Ruby:

Using blocks
The previous ruby example uses typical OO features, but the same effect can be accomplished with ruby's blocks in much less code.

Like Python, Scala also supports first-class functions. The following implements the basic functionality shown in the Python example.

}}