【一天一个设计模式】—— 策略模式 (Strategy Pattern)

定义

Define a family of algorithms,encapsulate each one,and make them interchangeable.
定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。

从定义可知,策略模式的策略即为封装算法的策略、选择算法的策略、互换算法的策略。在策略模式中,一个类的行为或其算法可以在运行时更改。这种设计模式属于行为型模式

UML图
在这里插入图片描述
从图中可知,策略模式由3部分组成:

1.抽象策略角色Strategy
各种策略、算法的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。

2.具体策略角色ConcreteStrategy
实现抽象策略中的操作,该类含有具体的算法。

3.封装角色Context
也称上下文角色,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。


该模式主要解决在有多种算法相似的情况下,使用大量判断所带来的复杂和难以维护的问题

代码:

1.创建Strategy

public interface Strategy{
    void algorithm();
}

2.创建ConcreteStrategy

public class Add implements Strategy{
   @Override
   public int algorithm(int n1, int n2) {
      return n1 + n2;
   }
}
public class Subtract implements Strategy{
   @Override
   public int algorithm(int n1, int n2) {
      return n1 - n2;
   }
}

3.创建Context

public class Context {
   private Strategy strategy;
   
   //doSomething
   public int executeStrategy(int n1, int n2) {
        if (strategy != null) {
            strategy.algorithm(n1, n2);
        }
    }
	//setStrategy更改算法
    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }
}

4.测试

public class Test{
   public static void main(String[] args) {
      Context context = new Context();
      //算法可以自由切换
      context.setStrategy(new Add());
      //1+2
      System.out.println(context.executeStrategy(1,2));
      
 	  context.setStrategy(new Subtract());   
 	  //1-2
      System.out.println(context.executeStrategy(1,2));

   }
}

关键代码为setStrategy

总结

1.优点:

  1. 策略可以自由切换、算法可以自由切换。
  2. 易于扩展增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“
  3. 避免使用多重条件选择语句(if-else)

2.缺点:

  1. 策略类会增多
  2. 所有策略类都需对外暴露

3.使用场景:

  1. 多个类只有在算法或行为上稍有不同的场景
  2. 算法需要自由切换的场景
  3. 需要屏蔽算法规则的场景
    —— ps:具体策略数量超过 4个,则需要考虑使用混合模式

版权声明:本文为intwei原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。