您的位置:首页 > 编程语言 > Python开发

python优雅实现策略模式

2017-02-05 19:25 369 查看
优雅实现策略模式; 在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: