SpecialistOff.NET / Вопросы / Статьи / Фрагменты кода / Резюме / Метки / Помощь / Файлы

Назад

Strategy: Choosing the Algorithm at Runtime


Метки: python

Strategy appears to be a family of Command classes, all inherited from the same base. But if you look at Command, you’ll see that it has the same structure: a hierarchy of function objects. The difference is in the way this hierarchy is used. As seen in patternRefactoring:DirList.py, you useCommand to solve a particular problem-in that case, selecting files from a list. The “thing that stays the same” is the body of the method that’s being called, and the part that varies is isolated in the function object. I would hazard to say that Command provides flexibility while you’re writing the program, whereas Strategy‘s flexibility is at run time.

Strategy also adds a “Context” which can be a surrogate class that controls the selection and use of the particular strategy object-just like State! Here’s what it looks like:

# FunctionObjects/StrategyPattern.py

# The strategy interface:
class FindMinima:
    # Line is a sequence of points:
    def algorithm(self, line) : pass

# The various strategies:
class LeastSquares(FindMinima):
    def algorithm(self, line):
        return [ 1.1, 2.2 ] # Dummy

class NewtonsMethod(FindMinima):
    def algorithm(self, line):
        return [ 3.3, 4.4 ]  # Dummy

class Bisection(FindMinima):
    def algorithm(self, line):
        return [ 5.5, 6.6 ] # Dummy

class ConjugateGradient(FindMinima):
    def algorithm(self, line):
        return [ 3.3, 4.4 ] # Dummy

# The "Context" controls the strategy:
class MinimaSolver:
    def __init__(self, strategy):
        self.strategy = strategy

    def minima(self, line):
        return self.strategy.algorithm(line)

    def changeAlgorithm(self, newAlgorithm):
        self.strategy = newAlgorithm

solver = MinimaSolver(LeastSquares())
line = [1.0, 2.0, 1.0, 2.0, -1.0, 3.0, 4.0, 5.0, 4.0]
print(solver.minima(line))
solver.changeAlgorithm(Bisection())
print(solver.minima(line))

Note similarity with template method - TM claims distinction that it has more than one method to call, does things piecewise. However, it’s not unlikely that strategy object would have more than one method call; consider Shalloway’s order fulfullment system with country information in each strategy.

Strategy example from standard Python: sort( ) takes a second optional argument that acts as a comparator object; this is a strategy.

Note

A better, real world example is numerical integration, shown here: http://www.rosettacode.org/wiki/Numerical_Integration#Python