Strategy Design Pattern

Kay Schluehr kay.schluehr at gmx.net
Fri Apr 21 04:05:18 EDT 2006


Daniel  Santa Cruz wrote:
> Hello all,
>
> I've been trying to go over my OO Patterns book, and I decided to try
> to implement them in Python this time around.  I figured this would
> help me learn the language better.

I guess it might help clarifying what OO is about since you see what
happens when you try to transform solutions across languages with very
different type systems.

> Well, I've gotten stuck with my first go at OO patterns with Python.  I
> guess it goes without say that some of the stuff that are taken for
> granted in most of the books (ie. Interfaces, Abstract classes) don't
> really apply to Python per say, but the idea behind the patterns can be
> extracted out still.  In the specific case of the Strategy pattern, I
> think the goal is to abstract out of the class an algorithm that can
> then be reused by some of the inherited classes.  This way we don't
> repeat ourselves.  Maybe I got this all wrong...

Well, yes, I disagree ;) From my point of view the StrategyPattern is
used to decouple the consumer/client/user of an algorithm from it's
implementation. If you need variations of the implementation of your
algo you don't want variations in the user. It's not about a tower of
abstractions in the Strategy itself. Those abstractions are there for
the purpose of enabling polymorphism.

If you want a straightforward translation you start with a Strategy
class and derive strategies from it:

class Strategy(object):
    def Evaluate(self):
         raise NotImplementedError    # making it abstract

class StrategyA(Strategy):
    def Evaluate(self):
         print "Evaluate StrategyA"

class StrategyB(Strategy):
    def Evaluate(self):
         print "Evaluate StrategyB"

This is very clean OO but you don't actually need the Strategy base
class because Pythons type system does not enforce a well known type at
compile time. In some sense also the StrategyX classes are overhead
because you can pass the Evaluate methods directly to the consumer:
functions are always first class objects. So the Strategy might be
reduced to:

def EvaluateA(self):
     print "Evaluate StrategyA"

def EvaluateB(self):
     print "Evaluate StrategyB"

def consumer(evaluate):
     evaluate()

>>> consumer(EvaluateB)
Evaluate StrategyB




More information about the Python-list mailing list