Strategy pattern

Strategy pattern

[
LePUS3 ( [http://lepus.org.uk/ref/legend/legend.xml legend] ) ] In computer programming, the strategy pattern (also known as the policy pattern) is a particular software design pattern, whereby algorithms can be selected at runtime.

In some programming languages, such as those without polymorphism, the issues addressed by this pattern are handled through forms of reflection, such as the native function pointer or function delegate syntax.

This pattern is invisible in languages with first-class functions. See the Python code for an example.

The strategy pattern is useful for situations where it is necessary to dynamically swap the algorithms used in an application. The strategy pattern is intended to provide a means to define a family of algorithms, encapsulate each one as an object, and make them interchangeable. The strategy pattern lets the algorithms vary independently from clients that use them.

Code Examples

C++


#include

using namespace std;

class StrategyInterface{ public: virtual void execute() = 0;};

class ConcreteStrategyA: public StrategyInterface{ public: virtual void execute() { cout << "Called ConcreteStrategyA execute method" << endl; ;

class ConcreteStrategyB: public StrategyInterface{ public: virtual void execute() { cout << "Called ConcreteStrategyB execute method" << endl; ;

class ConcreteStrategyC: public StrategyInterface{ public: virtual void execute() { cout << "Called ConcreteStrategyC execute method" << endl; ;

class Context{ private: StrategyInterface &_strategy;

public: Context(StrategyInterface& strategy):_strategy(strategy) { }

void execute() { _strategy.execute(); ;

int main(int argc, char *argv [] ){ ConcreteStrategyA concreteStrategyA; ConcreteStrategyB concreteStrategyB; ConcreteStrategyC concreteStrategyC;

Context contextA(concreteStrategyA); Context contextB(concreteStrategyB); Context contextC(concreteStrategyC);

contextA.execute(); contextB.execute(); contextC.execute();

return 0;}


= Java =

package wikipedia.patterns.strategy;

//StrategyExample test applicationpublic class StrategyExample {

public static void main(String [] args) { Context context;

// Three contexts following different strategies context = new Context(new ConcreteStrategyA()); context.execute();

context = new Context(new ConcreteStrategyB()); context.execute();

context = new Context(new ConcreteStrategyC()); context.execute(); // The classes that implement a concrete strategy should implement this // The context class uses this to call the concrete strategy interface IStrategy { void execute(); }

// Implements the algorithm using the strategy interface class ConcreteStrategyA implements IStrategy { public void execute() { System.out.println( "Called ConcreteStrategyA.execute()" ); } }

class ConcreteStrategyB implements IStrategy { public void execute() { System.out.println( "Called ConcreteStrategyB.execute()" ); } }

class ConcreteStrategyC implements IStrategy { public void execute() { System.out.println( "Called ConcreteStrategyC.execute()" ); } }

// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object class Context { IStrategy strategy;

// Constructor public Context(IStrategy strategy) { this.strategy = strategy; }

public void execute() { this.strategy.execute(); } }


= Python =

Python has first-class functions, so there's no need to implement this pattern explicitly. However one loses information because the interface of the strategy is not made explicit.Here's an example you might encounter in GUI programming, using a callback function:

class Button: """A very basic button widget.""" def __init__(self, submit_func, label): self.on_submit = submit_func # Set the strategy function directly self.label = label

# Create two instances with different strategiesbutton1 = Button(sum, "Add 'em")button2 = Button(lambda nums: " ".join(map(str, nums)), "Join 'em")

# Test each buttonnumbers = range(1, 10) # A list of numbers 1 through 9print button1.on_submit(numbers) # displays "45"print button2.on_submit(numbers) # displays "1 2 3 4 5 6 7 8 9"


= C# =

using System;

namespace Wikipedia.Patterns.Strategy{ // MainApp test application class MainApp { static void Main() { Context context;

// Three contexts following different strategies context = new Context(new ConcreteStrategyA()); context.Execute();

context = new Context(new ConcreteStrategyB()); context.Execute();

context = new Context(new ConcreteStrategyC()); context.Execute();

} }

// The classes that implement a concrete strategy should implement this // The context class uses this to call the concrete strategy interface IStrategy { void Execute(); }

// Implements the algorithm using the strategy interface class ConcreteStrategyA : IStrategy { public void Execute() { Console.WriteLine( "Called ConcreteStrategyA.Execute()" ); } }

class ConcreteStrategyB : IStrategy { public void Execute() { Console.WriteLine( "Called ConcreteStrategyB.Execute()" ); } }

class ConcreteStrategyC : IStrategy { public void Execute() { Console.WriteLine( "Called ConcreteStrategyC.Execute()" ); } }

// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object class Context { IStrategy strategy;

// Constructor public Context(IStrategy strategy) { this.strategy = strategy; }

public void Execute() { strategy.Execute(); }

ActionScript 3

//invoked from application.initializeprivate function init() : void{ var context:Context;

context = new Context( new ConcreteStrategyA() ); context.execute();

context = new Context( new ConcreteStrategyB() ); context.execute();

context = new Context( new ConcreteStrategyC() ); context.execute();}

package org.wikipedia.patterns.strategy{ public interface IStrategy { function execute() : void ;

package org.wikipedia.patterns.strategy{ public final class ConcreteStrategyA implements IStrategy { public function execute():void { trace( "ConcreteStrategyA.execute(); invoked" ); }

package org.wikipedia.patterns.strategy{ public final class ConcreteStrategyB implements IStrategy { public function execute():void { trace( "ConcreteStrategyB.execute(); invoked" ); }

package org.wikipedia.patterns.strategy{ public final class ConcreteStrategyC implements IStrategy { public function execute():void { trace( "ConcreteStrategyC.execute(); invoked" ); }

package org.wikipedia.patterns.strategy{ public class Context { private var strategy:IStrategy; public function Context(strategy:IStrategy) { this.strategy = strategy; } public function execute() : void { strategy.execute(); }

PHP

execute();

$context = new Context(new ConcreteStrategyB()); $context->execute();

$context = new Context(new ConcreteStrategyC()); $context->execute();

interface IStrategy { public function execute();}

class ConcreteStrategyA implements IStrategy { public function execute() { echo "Called ConcreteStrategyA execute method ";

class ConcreteStrategyB implements IStrategy { public function execute() { echo "Called ConcreteStrategyB execute method ";

class ConcreteStrategyC implements IStrategy { public function execute() { echo "Called ConcreteStrategyC execute method ";

class Context { var $strategy;

public function __construct(IStrategy $strategy) { $this->strategy = $strategy; }

public function execute() { $this->strategy->execute();

new StrategyExample;?>

Strategy versus Bridge

The UML class diagram for the Strategy pattern is the same as the diagram for the Bridge pattern. However, these two design patterns aren't the same in their "intent". While the Strategy pattern is meant for "behavior", the Bridge pattern is meant for "structure".

The coupling between the context and the strategies is tighter than the coupling between the abstraction and the implementation in the Bridge pattern.

Strategy Pattern and Open Closed Principle

According to Strategy pattern, the behaviors of a class should not be inherited, instead they should be encapsulated using interfaces. As an example, consider a car class. Two possible behaviors of car are brake and accelerate.

Since accelerate and brake behaviors change frequently between models, a common approach is to implement these behaviors in subclasses. This approach has significant drawbacks: accelerate and brake behaviors must be declared in each new Car model. This may not be a concern when there are only a small number of models, but the work of managing these behaviors increases greatly as the number of models increases, and requires code to be duplicated across models. Additionally, it is not easy to determine the exact nature of the behavior for each model without investigating the code in each.

The strategy pattern uses composition instead of inheritance. In the strategy pattern behaviors are defined as separate interfaces and specific classes that implement these interfaces. Specific classes encapsulate these interfaces. This allows better decoupling between the behavior and the class that uses the behavior. The behavior can be changed without breaking the classes that use it, and the classes can switch between behaviors by changing the specific implementation used without requiring any significant code changes. Behaviors can also be changed at run-time as well as at design-time. For instance, a car object’s brake behavior can be changed from BrakeWithABS() to Brake() by changing the brakeBehavior member to:

brakeBehavior = new Brake();

This gives greater flexibility in design and is in harmony with the Open/closed principle (OCP) that states classes should be open for extension but closed for modification.

ee also

*Mixin
*Policy-based design
*First-class function
*Template method pattern
*Bridge pattern
*Open/closed principle
*Factory Pattern
*List of object-oriented programming terms

External links

* [http://www.netobjectivesrepository.com/TheStrategyPattern The Strategy Pattern from the Net Objectives Repository]
* [http://www.javaworld.com/javaworld/jw-04-2002/jw-0426-designpatterns.html Strategy Pattern for Java article]
* [http://www.lepus.org.uk/ref/companion/Strategy.xml Strategy pattern in UML and in LePUS3] (a formal modelling notation)
* [http://www.dofactory.com/Patterns/PatternStrategy.aspx Data & object factory]
* [http://www.refactoring.com/catalog/replaceTypeCodeWithStateStrategy.html Refactoring: Replace Type Code with State/Strategy]
* [http://www.fsw.com/Jt/Jt.htm Jt] J2EE Pattern Oriented Framework
* [http://anirudhvyas.com/root/2008/04/02/a-much-better-strategy-pattern/ Strategy Pattern with a twist!]


Wikimedia Foundation. 2010.

Игры ⚽ Нужно сделать НИР?

Look at other dictionaries:

  • Strategy Pattern — Die Strategie (engl. Strategy) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört zu der Kategorie der Verhaltensmuster (Behavioural Patterns). Das Muster definiert eine Familie austauschbarer Algorithmen. Es ist eines der… …   Deutsch Wikipedia

  • Strategy pattern — Die Strategie (engl. Strategy) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört zu der Kategorie der Verhaltensmuster (Behavioural Patterns). Das Muster definiert eine Familie austauschbarer Algorithmen. Es ist eines der… …   Deutsch Wikipedia

  • Strategy — A Strategy is a long term plan of action designed to achieve a particular goal, most often winning. Strategy is differentiated from tactics or immediate actions with resources at hand by its nature of being extensively premeditated, and often… …   Wikipedia

  • Strategy (disambiguation) — A strategy is a long term plan of action designed to achieve a particular goal.Strategy may also refer to:In business: * Business strategy, the art and science of enabling an organization to achieve its objective ** Marketing strategy, a process… …   Wikipedia

  • Strategy video game — Part of a series on …   Wikipedia

  • Pattern recognition — is a sub topic of machine learning. It is the act of taking in raw data and taking an action based on the category of the data .citation needed|date=September 2008 Most research in pattern recognition is about methods for supervised learning and… …   Wikipedia

  • Strategy Safari — (FT Prentice Hall, 2002), subtitled A Guided Tour Through the Wilds of Strategic Management by Henry Mintzberg, Bruce Ahlstrand and Joseph Lampel is an overview of the full field of academic and business studies of strategy, based on a previous… …   Wikipedia

  • Strategy dynamics — The word ‘dynamics’ appears frequently in discussions and writing about strategy, and is used in two distinct, though equally important senses.The dynamics of strategy and performance concerns the ‘content’ of strategy – initiatives, choices,… …   Wikipedia

  • Pattern Recognition (novel) — infobox Book | name = Pattern Recognition image caption = Original 1st edition cover author = William Gibson cover artist = country = United States language = English series = genre = Science fiction novel publisher = G. P. Putnam s Sons release… …   Wikipedia

  • strategy — /strat i jee/, n., pl. strategies. 1. Also, strategics. the science or art of combining and employing the means of war in planning and directing large military movements and operations. 2. the use or an instance of using this science or art. 3.… …   Universalium

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”