目录
策略模式
模板方法模式
策略模式
定义一个个算法,把它们封装起来,并且使它们可以相互替换。本模式使得算法可独立于使用它的客户而变化。角色有:抽象策略、具体策略和上下文。
from abc import abstractmethod, ABCMeta
from datetime import datetime
# 抽象策略
class Strategy(metaclass=ABCMeta):
@abstractmethod
def execute(self, data):
pass
# 具体策略
class FastStrategy(Strategy):
def execute(self, data):
print("使用较快的策略处理%s" % data)
# 具体策略
class SlowStrategy(Strategy):
def execute(self, data):
print("使用较慢的策略处理%s" % data)
# 上下文
class Context:
def __init__(self, strategy, data):
self.data = data
self.strategy = strategy
# 可以定义用户不知道的东西
self.date = datetime.now()
def set_strategy(self, strategy):
self.strategy = strategy
def do_strategy(self):
self.strategy.execute(self.data)
data = "Hello!"
# 使用较快的策略处理
fast_strategy = FastStrategy()
context = Context(fast_strategy, data)
context.do_strategy()
# 使用较慢的策略处理
slow_strategy = SlowStrategy()
context = Context(slow_strategy, data)
context.do_strategy()
"""
使用较快的策略处理Hello!
使用较慢的策略处理Hello!
"""
优点:定义了一些列可重用的算法和行为;消除了一些条件语句;可以提供相同行为的不同实现;缺点:客户必须了解不同的策略。
模板方法模式
内容:定义一个操作中的算法骨架,将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。使用模板方法,需要用到两种角色,分别是抽象类和具体类。抽象类的作用是是定义抽象类(钩子操作),实现一个模板方法作为算法的骨架。具体类的作用实现原子操作。
from abc import ABCMeta, abstractmethod
from time import sleep
# 抽象类
class Window(metaclass=ABCMeta):
@abstractmethod
def start(self): # 原子操作/钩子操作
pass
@abstractmethod
def repaint(self): # 原子操作/钩子操作
pass
@abstractmethod
def stop(self): # 原子操作/钩子操作
pass
def run(self):
"""
模板方法(具体方法),这个大逻辑就不需要自己写了
:return:
"""
self.start()
while True:
try:
self.repaint()
sleep(1)
except KeyboardInterrupt:
break
self.stop()
# 具体类
class MyWindow(Window):
def __init__(self, msg):
self.msg = msg
def start(self):
print('窗口开始运行!')
def stop(self):
print('窗口停止运行!')
def repaint(self):
print(self.msg)
MyWindow("Hello...").run()
模板方法适用的场景:一次性实现一个算法的不变部分,各个子类中的公共行为应该被提取出来并集中到一个公共父类中以避免代码重复;控制子类扩展。