上一篇《观察者模式》 下一篇《建造者模式》
策略模式,它是一种行为型设计模式,它定义了算法族,分别封装起来,让它们之间可以互相替换。策略模式让算法的变化独立于使用算法的客户,降低了耦合,增加了系统的可维护性和可扩展性。
策略模式的结构包括三种角色:
1、策略(Strategy):策略是一个接口,该接口定义了算法标识。
2、具体策略(ConcreteStrategy):具体策略是实现策略接口的类,具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体算法。
3、上下文(Context):上下文是依赖于策略接口的类,即上下文包含有策略声明的变量。上下文中提供了一个方法,该方法委托策略变量调用具体策略所实现的策略接口中的方法。
策略模式的使用场景:
1、针对同一类型问题的多种处理方式,但具体行为有差别时。
2、需要安全地封装多种同一类型的操作时。
3、出现同一抽象类有多个子类,而又需要使用 if-else 或者 switch-case 来选择具体子类时。
4、当业务功能是客户程序的一个难以分割的成分时,增加新的业务算法或改变现有算法将十分困难。
5、当不同的时候需要不同的算法,我们不想支持我们并不使用的业务算法时。
6、当算法使用了客户不应该知道的数据时。
7、当一个类定义了很多行为,而且这些行为在这个类里的操作以多个条件语句的形式出现时。
总之,策略模式是一种非常实用的设计模式,可以用于封装各种类型的规则,并且可以在不同的时间应用不同的业务规则。
策略模式的创建步骤:
1、定义策略接口:首先需要定义一个策略接口,该接口中包含算法的方法。
2、创建具体策略类:根据策略接口,创建实现具体算法的类。
3、创建上下文类:上下文类负责维护和查询策略对象,并在具体策略类中注入策略对象。
4、在上下文类中注入策略对象:通过构造函数或者setter方法,将策略对象注入到上下文类中。
5、在客户端中创建上下文对象:在客户端中创建上下文对象,并将具体策略对象注入到上下文对象中。
6、客户端调用上下文对象:客户端通过上下文对象调用具体策略对象的方法,实现算法的调用。
以上是策略模式的基本创建步骤,具体实现方式可能会因语言和需求而有所不同。
策略模式的优点,主要包括:
1、提供了对“开闭原则”的完美支持,可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
2、提供了管理相关的算法族的办法,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
3、提供了可以替换继承关系的办法,使得系统更加灵活和可维护。
4、使用策略模式可以避免使用多重条件转移语句,如 if...else 语句、switch...case 语句。
5、可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的实现方式。
策略模式的缺点,主要包括:
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类,这可能违反了“开闭原则”。
2、策略模式会造成产生很多策略类,增加了系统的复杂性和维护成本。
3、在实现上,策略模式需要使用继承和多态,这会增加代码的复杂性和实现的难度。
4、在使用策略模式时,需要注意策略的正确性和稳定性,因为不同的策略可能会对系统的行为产生不同的影响。
总之,策略模式虽然可以提高系统的灵活性和可维护性,但也存在一些缺点需要注意。在使用策略模式时,需要根据具体情况进行权衡和考虑。

以下是一个示例,展示了如何在C#中实现策略模式:
- //定义策略接口
- public interface Strategy
- {
- void Execute();
- }
- //创建具体策略类
- public class ConcreteStrategyA : Strategy
- {
- public void Execute()
- {
- Console.WriteLine("执行策略A");
- }
- }
-
- public class ConcreteStrategyB : Strategy
- {
- public void Execute()
- {
- Console.WriteLine("执行策略B");
- }
- }
- //创建上下文类
- public class Context
- {
- private Strategy strategy;
-
- public Context(Strategy strategy)
- {
- this.strategy = strategy;
- }
-
- public void SetStrategy(Strategy strategy)
- {
- this.strategy = strategy;
- }
-
- public void DoSomething()
- {
- strategy.Execute();
- }
- }
- //在客户端中创建上下文对象并注入具体策略对象
- public class Client{
- public void Test(){
- Context context = new Context(new ConcreteStrategyA());
- context.DoSomething(); // 输出:执行策略A
- context.SetStrategy(new ConcreteStrategyB());
- context.DoSomething(); // 输出:执行策略B
- }
- }
策略模式通常通过以下方式实现:
- //定义策略接口
- public interface Strategy {
- void execute();
- }
- //创建具体策略类
- public class ConcreteStrategyA implements Strategy {
- @Override
- public void execute() {
- System.out.println("执行策略A");
- }
- }
-
- public class ConcreteStrategyB implements Strategy {
- @Override
- public void execute() {
- System.out.println("执行策略B");
- }
- }
- //创建上下文类
- public class Context {
- private Strategy strategy;
-
- public Context(Strategy strategy) {
- this.strategy = strategy;
- }
-
- public void setStrategy(Strategy strategy) {
- this.strategy = strategy;
- }
-
- public void doSomething() {
- strategy.execute();
- }
- }
- //在客户端中创建上下文对象并注入具体策略对象
- public class Main {
- public static void main(String[] args) {
- Context context = new Context(new ConcreteStrategyA());
- context.doSomething(); // 输出:执行策略A
- context.setStrategy(new ConcreteStrategyB());
- context.doSomething(); // 输出:执行策略B
- }
- }
在JavaScript中,策略实现方式如下:
- //定义策略接口
- function Strategy(execute) {
- this.execute = execute;
- }
- //创建具体策略类
- class ConcreteStrategyA extends Strategy {
- constructor() {
- super(this.execute);
- }
-
- execute() {
- console.log('执行策略A');
- }
- }
-
- class ConcreteStrategyB extends Strategy {
- constructor() {
- super(this.execute);
- }
-
- execute() {
- console.log('执行策略B');
- }
- }
- //创建上下文类
- class Context {
- constructor(strategy) {
- this.strategy = strategy;
- }
-
- setStrategy(strategy) {
- this.strategy = strategy;
- }
-
- doSomething() {
- this.strategy.execute();
- }
- }
-
- //在客户端中创建上下文对象并注入具体策略对象
- const context = new Context(new ConcreteStrategyA());
- context.doSomething(); // 输出:执行策略A
- context.setStrategy(new ConcreteStrategyB());
- context.doSomething(); // 输出:执行策略B
以下是在C++中实现策略模式:
- //定义策略接口
- class Strategy {
- public:
- virtual void execute() = 0;
- };
- //创建具体策略类
- class ConcreteStrategyA : public Strategy {
- public:
- void execute() override {
- cout << "执行策略A" << endl;
- }
- };
-
- class ConcreteStrategyB : public Strategy {
- public:
- void execute() override {
- cout << "执行策略B" << endl;
- }
- };
- //创建上下文类
- class Context {
- public:
- Context(Strategy* strategy) : strategy_(strategy) {}
- void setStrategy(Strategy* strategy) {
- strategy_ = strategy;
- }
- void doSomething() {
- strategy_->execute();
- }
- private:
- Strategy* strategy_;
- };
- //在客户端中创建上下文对象并注入具体策略对象
- int main() {
- Context context(new ConcreteStrategyA());
- context.doSomething(); // 输出:执行策略A
- context.setStrategy(new ConcreteStrategyB());
- context.doSomething(); // 输出:执行策略B
- delete context.strategy_;
- delete context;
- return 0;
- }
以下是在python中实现策略模式:
- //定义策略接口
- from abc import ABC, abstractmethod
-
- class Strategy(ABC):
- @abstractmethod
- def execute(self):
- pass
-
- //创建具体策略类
- class ConcreteStrategyA(Strategy):
- def execute(self):
- print("执行策略A")
-
- class ConcreteStrategyB(Strategy):
- def execute(self):
- print("执行策略B")
-
- //创建上下文类
- class Context:
- def __init__(self, strategy):
- self.strategy = strategy
-
- def set_strategy(self, strategy):
- self.strategy = strategy
-
- def do_something(self):
- self.strategy.execute()
-
- //在客户端中创建上下文对象并注入具体策略对象
- context = Context(ConcreteStrategyA())
- context.do_something() # 输出:执行策略A
- context.set_strategy(ConcreteStrategyB())
- context.do_something() # 输出:执行策略B
以下是一个示例,展示了如何在go中实现策略模式:
- //定义策略接口
- type Strategy interface {
- Execute()
- }
- //创建具体策略类
- type ConcreteStrategyA struct{}
-
- func (s *ConcreteStrategyA) Execute() {
- fmt.Println("执行策略A")
- }
-
- type ConcreteStrategyB struct{}
-
- func (s *ConcreteStrategyB) Execute() {
- fmt.Println("执行策略B")
- }
- //创建上下文类
- type Context struct {
- strategy Strategy
- }
-
- func (c *Context) SetStrategy(strategy Strategy) {
- c.strategy = strategy
- }
-
- func (c *Context) DoSomething() {
- c.strategy.Execute()
- }
- //在客户端中创建上下文对象并注入具体策略对象
- func main() {
- context := &Context{}
- context.SetStrategy(&ConcreteStrategyA{})
- context.DoSomething() // 输出:执行策略A
- context.SetStrategy(&ConcreteStrategyB{})
- context.DoSomething() // 输出:执行策略B
- }
以下是一个示例,展示了如何在PHP中实现策略模式:
- //定义策略接口
- interface Strategy {
- public function execute();
- }
- //创建具体策略类
- class ConcreteStrategyA implements Strategy {
- public function execute() {
- echo "执行策略A";
- }
- }
-
- class ConcreteStrategyB implements Strategy {
- public function execute() {
- echo "执行策略B";
- }
- }
- //创建上下文类
- class Context {
- private $strategy;
-
- public function __construct(Strategy $strategy) {
- $this->strategy = $strategy;
- }
-
- public function setStrategy(Strategy $strategy) {
- $this->strategy = $strategy;
- }
-
- public function doSomething() {
- $this->strategy->execute();
- }
- }
- //在客户端中创建上下文对象并注入具体策略对象
- $context = new Context(new ConcreteStrategyA());
- $context->doSomething(); // 输出:执行策略A
- $context->setStrategy(new ConcreteStrategyB());
- $context->doSomething(); // 输出:执行策略B
通过以上步骤,我们实现了策略模式,使得算法可以独立于使用它的客户端,并且可以在不修改原有系统的基础上选择算法或行为。这种设计模式使得程序更加灵活和可维护。策略模式体现了开闭原则和里氏替换原则,各个策略实现都是兄弟关系,实现了同一个接口或者继承了同一个抽象类。这样只要使用策略的客户端保持面向抽象编程,就可以动态地切换不同的策略实现以进行替换。
《完结》
上一篇《观察者模式》 下一篇《建造者模式》