策略模式

一.什么是策略模式

  定义:定义一组算法,将每个算法封装起来,并且使它们之间可以互相转换

二.类图

  

  Context封装角色:

    也叫做上下文角色,起承上启下封装作用

  Strategy抽象策略角色:

    策略、算法的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性

  ConcreteStrategy具体策略角色:

    实现抽象策略中的操作,该类含有具体的算法

三.代码实现

1.抽象的策略角色Strategy

  抽象出具体策略角色子类中共有的方法

1 public interface Strategy {
2     //策略模式的运算法则
3     public void doSomething();
4 }

2.具体策略角色ConcreteStrategy1

  封装的具体策略方法一

1 public class ConcreteStrategy1 implements Strategy {
2     @Override
3     public void doSomething() {
4         System.out.println("策略模式法则1");
5     }
6 }

3.具体策略角色ConcreteStrategy2

  封装的具体策略方法二

1 public class ConcreteStrategy2 implements Strategy{
2     @Override
3     public void doSomething() {
4         System.out.println("策略模式法则2");
5     }
6 }

4.封装角色

  借用代理模式的思路

  策略模式和代理模式的差距就是:策略模式的封装角色和被封装的策略类不是实现同一接口,而代理模式实现的是同一接口

 1 public class Context {
 2     //抽象策略
 3     private Strategy strategy;
 4     //构造函数设置具体策略
 5     public Context(Strategy strategy){
 6         this.strategy = strategy;
 7     }
 8     //封装后的策略方法
 9     public void doAnything(){
10         strategy.doSomething();
11     }
12 }

5.主函数

  要想实现哪一个策略,首先利用多态new出对象

  其次new出封装角色对象

  最后使用new出的封装角色对象调用封装后的策略方法

 1 public class Client {
 2     public static void main(String[] args) {
 3         //声明一个具体策略
 4         Strategy strategy = new ConcreteStrategy1();
 5         //声明上下文对象
 6         Context context = new Context(strategy);
 7         //执行封装后的方法
 8         context.doAnything();
 9     }
10 }

四.策略模式的优点

  1.算法之间可以自由切换。只要实现抽象策略,它就成为抽象家族的一个成员,通过封装角色对其进行封装,保证对外提供“可自由切换”的策略

  2.避免使用多重条件判断。若没有策略模式,系统无法通过其他方式知道何时使用哪种策略,只能通过if条件进行判断,大量代码冗余

  3.扩展性良好。系统中增加新的策略时,只要实现接口就可以了

五.策略模式缺点

  1.策略模式类数量多。每一个策略都是一个类,复用性小,类数量增多

  2.所有策略模式都需要对外暴露。上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则相违背,我只是使用了一个策略,我凭什么就要了解这个策略呢?那封装还有什么意义呢?这个缺点我们可以通过工厂方法模式、代理模式或享元模式修正

六.策略模式使用场景

  1.多个类只有在算法或行为上稍有不同的场景

  2.算法需要自由切换的场景

七.策略模式注意事项

  如果一个系统中的一个策略家族的具体策略数量超过4个,则需要老驴使用混合模式解决策略类膨胀和对外暴露的问题,否则后期维护会很麻烦

原文地址:https://www.cnblogs.com/lyc-code/p/12386594.html