Strategy pattern

The strategy (English strategy ) is a design pattern in the field of software development and belongs to the category of behavior ( behavioral patterns ). The pattern defines a family of interchangeable algorithms. It is one of the so-called GoF patterns.

  • 6.1 C function pointers
  • 6.2 Java
  • Ruby 6.3
  • Python 6.4

Use

Strategy objects are used similar to class libraries. In contrast, however, it is not about external program parts that can be used as a toolkit, but an integral component of the program itself, which have therefore been identified as separate objects so they can be replaced by other algorithms.

Mostly a strategy is implemented by classes that implement a particular interface. In languages ​​such as Smalltalk, in which also the program code can be stored even in objects, a strategy code objects can also be realized by such.

The use of strategies makes sense if

  • Many related classes differ only in their behavior.
  • Different ( interchangeable ) versions of an algorithm are needed.
  • Data should be hidden within an algorithm before clients.
  • Different behaviors are firmly integrated within a class (usually on multiple branches) but the algorithms used are to be reused or
  • The class should be made more flexible.

UML diagram

Declaration of actors

The class strategy only defines an interface ( interface) for all supported algorithms. The implementation of the actual algorithms can be found only in leads again ( concrete strategy ).

The context keeps a member variable of the interface strategy, which is occupied with a reference to the desired object strategy. In this way, the concrete algorithm on the interface is included and can be replaced if necessary even dynamically at runtime with another implementation.

Benefits

  • It is defined a family of algorithms.
  • It allows the selection of different implementations and thereby the flexibility and reusability increase.
  • Multiple junctions can be prevented, and this increases the overview of the code.
  • Strategies provide an alternative to subclassing of contexts.

Disadvantages

  • Clients need to know the different strategies in order to choose between them and initialize the context.
  • Compared to the implementation of the algorithms in the context created here an additional communication overhead between Strategy and Context.
  • The number of objects increases.

Example

As an example, a tax calculation program used, which should outsource the calculation of tax rates as possible in strategy objects to be easily configurable depending on the country.

Another example would be saving a document or graphic in different file formats.

A packer, which supports different compression algorithms may be implemented by means of strategy. In Java, design patterns, for example, to delegate the layout of AWT components to appropriate layout manager ( BorderLayout, FlowLayout, etc.) is used.

Other examples ( outside the OOP world):

  • Database Systems
  • File Systems
  • Device driver
  • Server programs

Code examples

C function pointers

# include   class Example { public:      Example (); setStrategy void (void (*) ()); void (* _strategy ) (); void strategy (); };   Example :: Example () { _strategy = 0; }   void Example :: setStrategy (void (* fnc ) () ) { Example :: _strategy = fnc; }   void Example :: strategy () { if ( _strategy ) _strategy (); }   class strategies { public: static void strategy1 () { std :: cout << " Hello World \ n "; } static void strategy2 () { std :: cout << " FOO"; } static void strategy3 () { std :: cout << " BAR "; } };   int main () { Example c;            c.setStrategy (& ( strategies :: strategy1 ) ); c.strategy ();   c.setStrategy (& ( strategies :: strategy2 ) ); c.strategy ();   c.setStrategy (& ( strategies :: strategy3 ) ); c.strategy ();   return 0; } Java

Class client { public static void main ( final String [ ] ARGS ) { K context = new Context (); k.setStrategie (new KonkreteStrategieA ()); k.arbeite (); / / " Path A " k.setStrategie (new KonkreteStrategieB ()); k.arbeite (); / / " Path B " } }     class Context { private Strategy strategy = null;   public void setStrategie (final Strategy STRATEGY ) { strategy = STRATEGY; }   public void work () { if ( strategy! = null) strategie.algorithmus (); } }   interface Strategy { void algorithm (); }   KonkreteStrategieA class implements Strategy { public void algorithm () { System.out.println (" Path A "); } }   KonkreteStrategieB class implements Strategy { public void algorithm () { System.out.println (" path B "); } } Ruby

Class Context    def initialize ( strategy )      @ strategy = strategy    end      def execute      raise ' strategy object does not respond to the execute method '        [email protected]_to? (: execute )      @ strategy.execute    end end   class StrategyA    def execute       puts ' The normal way '    end end   class StrategyB    def execute       puts ' Another way '    end end   class StrategyC    def execute       puts ' Yet another way '    end end   a = Context.new ( StrategyA.new ) a.execute # The normal way   b = Context.new ( StrategyB.new ) b.execute # Another way   c = Context.new ( StrategyC.new ) c.execute # Yet another way Python

Class Context (object):      def __ init__ (self, strategy ):          self.strategy = strategy        def execute (self, a, b):          self.strategy.execute return (a, b )     AddStrategy class (object):      def execute (self, a, b):          return a b     SubtractStrategy class (object):      def execute (self, a, b):          return a - b     context = Context ( AddStrategy ()) print ( 3 = '4 ' context.execute (4, 3 ) ) # 4 3 = 7   context.strategy = SubtractStrategy () print ( '4 - 3 = ', context.execute (4, 3 ) ) # 4 - 3 = 1 Related Design Patterns

  • Abstract factory
  • Adapter
  • Decorator
  • Template Method
  • State
751301
de