优雅实现策略模式; 在awesome-python上有一个关于模式设计的包,对包中的代码做了一点修改。BaseStrateby最核心的方法是select.
# -*- coding: utf-8 -*- """ http://stackoverflow.com/questions/963965/how-is-this-strategy-pattern -written-in-python-the-sample-in-wikipedia In most of other languages Strategy pattern is implemented via creating some base strategy interface/abstract class and subclassing it with a number of concrete strategies (as we can see at http://en.wikipedia.org/wiki/Strategy_pattern), however Python supports higher-order functions and allows us to have only one class and inject functions into it's instances, as shown in this example. """ import types import random class BaseStrategy: def __init__(self, func=None): if func is not None: self.select(func) def __call__(self, *args, **kwargs): self.execute(*args, **kwargs) def execute(self, *args, **kwargs): pass def select(self, func): # redefine a method self.execute = types.MethodType(func, self) class StrategyExample(BaseStrategy): def __init__(self, func=None): self.name = 'Strategy Example 0' if func is not None: self.select(func) def execute(self, arg='nothing'): print(arg) def make(self): self.select(execute_replacement1) def random(self): r = random.random() if r > 0.5: self.select(execute_replacement1) else: self.select(execute_replacement2) # strategies def execute_replacement1(obj, s=' from execute'): print(obj.name + s + '1') def execute_replacement2(obj, s=' from execute'): print(obj.name + s + '2') class SubStrategy(StrategyExample): def __init__(self, func=None): super(SubStrategy, self).__init__(func) self.name = 'Strategy Example x' if __name__ == '__main__': strat0 = StrategyExample() stratx = SubStrategy() stratx() strat1 = StrategyExample(execute_replacement1) strat1.name = 'Strategy Example 1' strat2 = StrategyExample(execute_replacement2) strat2.name = 'Strategy Example 2' strat0() strat1() strat2() strat2.select(execute_replacement1) strat2() for k in range(5): stratx = SubStrategy() stratx.random() stratx('shit') ### OUTPUT ### # nothing # nothing # Strategy Example 1 from execute 1 # Strategy Example 2 from execute 2 # Strategy Example 2 from execute 1 # Strategy Example xshit # Strategy Example xshit # Strategy Example xshit # Strategy Example xshit # Strategy Example xshit
