前言
在软件开发的过程中,完成一项任务,往往可以用多种不同的方式,每一种方式就是一种策略,我们选择不同的策略来完成任务;在某些情况下,需要提供多种策略,比如提供多种排序算法;提供多种策略的方式可以是以硬编码的方式,即在代码中通过条件判断,这样的方式容易使得我们的代码变得臃肿,维护起来也异常困难;另一种方式是将算法封装成一个类,由客户端去选择想要执行的类。
定义
策略模式是一种行为型设计模式,策略模式定义了算法簇,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
模式结构
策略模式类图:
模式分析
环境类: 也叫上线文,对策略进行二次封装,避免客户端直接调用具体的策略类。
抽象策略类: 定义了策略的接口,也可以抽象一些公共的方法。
具体策略类: 实现具体的算法类。
代码实现(python)
class Context(object):
def algo(self):
self._strategy.algo()
def set_strategy(self, strategy: Strategy):
self._strategy = strategy
class Strategy(object):
def algo(self):
raise NotImpletementedError
class ConcreteStrategyA(Strategy):
def algo(self):
print('Concreate Strategy A')
class ConcreteStrategyB(Strategy):
def algo(self):
print('Concreate Strategy B')
优缺点
优点:
- 完美实现开闭原则,易于扩展,客户端可以自由切换新的策略
- 提供了一种替换继承关系的方法
- 避免使用繁复的条件语句
缺点:
- 客户端必须知道所有的策略类,自行决定使用哪种
- 可能会产生过多的策略类,维护这些类可能会有一定的困难
适用情况
- 许多相关的类仅仅是行为有异,“策略”提供了一种用多个行为中的一个行为来配置一个类的方法;
- 需要使用一个算法的不同变体;
- 算法使用客户不应该知道的数据;
- 一个类定义了多种行为,并且这些行为在这个类中的操作中已多个条件语句的形式出现,将相关的条件分支移入他们各自的策略中,已替代这些语句。
参考
https://wiki.jikexueyuan.com/project/java-design-pattern/strategy-pattern.html
https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/strategy.html