策略模式是一种常见的软件设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,这种模式使得算法可以独立于使用它的客户端而变化。
策略模式的主要优点是提供了管理相关的算法族的办法,策略类的等级结构定义了一个算法或行为族,恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码,策略模式提供了一种方式来控制算法群中各个算法之间的关系,避免了难以维护的问题。
策略模式通常涉及三个角色:环境类、抽象策略类和具体策略类,环境类是持有一个策略类的引用,提供使用接口给客户端;抽象策略类定义了一组算法,负责具体的算法实现;具体策略类实现了抽象策略类中的算法。
策略模式的使用场景包括:需要在不同时间应用不同的算法,如果这些算法在概念上差别很大,且彼此之间不会影响到的话;需要动态地选择算法,如果算法以参数的形式传递给客户端的话。
在使用策略模式时,需要注意以下几点:客户端必须知道所有的策略类,并自行决定使用哪一个策略类;共同的行为应该被提取出来并放在环境类里面,这个环境类一般是一个抽象类,不能被实例化;具体策略类也要承担一些职责,如初始化操作,取消操作等。
下面是一个使用Python实现的策略模式的例子,在这个例子中,我们定义了一个名为Strategy
的抽象策略类,以及两个具体策略类ConcreteStrategyA
和ConcreteStrategyB
,环境类Context
持有一个策略类的引用,并提供一个接口供客户端使用。
from abc import ABC, abstractmethod 定义一个抽象策略类 class Strategy(ABC): @abstractmethod def execute(self, data): pass 定义一个具体策略类A class ConcreteStrategyA(Strategy): def execute(self, data): return data + ': The result of the strategy A.' 定义一个具体策略类B class ConcreteStrategyB(Strategy): def execute(self, data): return data + ': The result of the strategy B.' 定义环境类 class Context: def __init__(self, strategy: Strategy): self._strategy = strategy @property def strategy(self): return self._strategy @strategy.setter def strategy(self, strategy: Strategy): self._strategy = strategy def do_something(self, data): return self._strategy.execute(data) 客户端代码 if __name__ == '__main__': context = Context(ConcreteStrategyA()) print(context.do_something('Hello')) context.strategy = ConcreteStrategyB() print(context.do_something('World'))
在这个例子中,当我们改变Context
对象的策略时,do_something
方法的输出也会随之改变,这就是策略模式的魅力所在,它可以让我们在运行时动态地改变算法。