第十五章 策略模式
1. 核心思想
定义一系列算法,将每个算法都封装起来,并且使它们之间可以相互替换。策略模式使算法可以独立于使用它的用户而变化。
比如在生活中,将不同的出行方式(采用的交通工具)理解成一种出行算法,将这些算法抽象出一个基类IVehicle,并定义一系列算法:共享单车(SharedBicycle)、快速公交(ExpressBus)、地铁(Subway)、快车(Express)…。我们可以选择任意一种(实际场景中肯定会选择最合适的)出行方式,并且可以方便地更换出行方式。
策略模式的核心思想:对算法、规则进行封装,使得替换算法和新增算法更加灵活。
2. UML类图
3. 框架代码
from abc import ABC,abstractmethod
import sys
class Strategy(ABC):
@abstractmethod
def algorithmInterface(self):
pass
class StrategyImplA(Strategy):
def algorithmInterface(self):
print(f"{self.__class__.__name__}/{sys._getframe().f_code.co_name} is running...")
class StrategyImplB(Strategy):
def algorithmInterface(self):
print(f"{self.__class__.__name__}/{sys._getframe().f_code.co_name} is running...")
class StrategyImplC(Strategy):
def algorithmInterface(self):
print(f"{self.__class__.__name__}/{sys._getframe().f_code.co_name} is running...")
class Context:
def __init__(self,strategy:Strategy): # 初始化时,传入具体的策略对象
self.strategy=strategy
def contextInterface(self): # 根据具体的策略对象,调用其算法的方法
self.strategy.algorithmInterface()
if __name__ == "__main__":
context=Context(StrategyImplA())
context.contextInterface()
context=Context(StrategyImplB())
context.contextInterface()
context=Context(StrategyImplC())
context.contextInterface()
4. 模型说明
4.1 设计要点
策略模式中主要有三个角色,在设计策略模式时要找到并区分这些角色。
- 上下文环境(Context):起着承上启下的封装作用,屏蔽上层应用对策略(算法)的直接访问,封装可能存在的变化。
- 策略的抽象(Strategy):策略(算法)的抽象类,定义统一的接口,规定每个子类必须实现的方法。
- 具备的策略:策略的具体实现者,可以有多个不同的(算法或规则)实现。
4.2 优缺点
- 优点
- 算法(规则)可自由切换。
- 避免使用多重条件判断。
- 方便拓展和增加新的算法(规则)。
- 缺点:所有策略类都需要对外暴露。
5. 应用场景
- 如果一个系统里面有许多类,它们之间的区别仅在于有不同的行为,那么可以使用策略模式动态地让一个对象在许多行为中选择一种;
- 一个系统需要动态地在几种算法中选择一种;
- 设计程序接口时希望部分内部实现由调用方自己实现;
- 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合;