其他分享
首页 > 其他分享> > “策略模式”原来如此简单

“策略模式”原来如此简单

作者:互联网

一、策略模式简介

1、定义

策略模式(Strategy):将一组算法封装起来,使其可以相互替换;同时算法的变化不会影响客户的使用

 2、使用场景

可以用它来封装几乎任何类型的规则只要在分析过程中听到需要在不同条件下应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性

3、优缺点

优点:

  • 算法可以自由切换
  • 避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护)
  • 扩展性良好,增加一个策略只需实现接口即可

缺点:

  • 策略类数量会增多,每个策略都是一个类,复用的可能性很小
  • 所有的策略类都需要对外暴露

3、UML类图

 


 二、策略模式实现

1、策略角色

 抽象策略角色,是对策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。algorithm是“运算法则”的意思。

package com.mfc.design.策略模式;

/**
 * @author MouFangCai
 * @date 2019/10/11 11:28
 */
public abstract class Strategy {

    // 算法方法
    public abstract void algorithmInterface();
}

2、具体策略角色

用于实现抽象策略中的操作,即实现具体的算法,下方用print代替。测试类共3个ConcreteStrategy,其它两个类与ConcreteStrategyA同理,就不再赘述了。

package com.mfc.design.策略模式;

/**
 * @author MouFangCai
 * @date 2019/10/11 11:31
 */
public class ConcreteStrategyA extends Strategy {
    @Override
    public void algorithmInterface() {
        System.out.println("这是算法A");
    }
}

3、 Context上下文

 Context上下文角色,也叫Context封装角色,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。

package com.mfc.design.策略模式;

/**
 * @author MouFangCai
 * @date 2019/10/11 11:32
 */
public class Context {

    Strategy strategy;

    public Context (Strategy strategy) {
        // 初始化时,传入具体的策略对象
        this.strategy = strategy;
    }

    // 上下文接口
    public void ContextInterface() {
        // 根据具体的策略对象,调用就其算法的方法
        strategy.algorithmInterface();
    }
}

 4、Client客户端

package com.mfc.design.策略模式;

/**
 * @author MouFangCai
 * @date 2019/10/11 11:36
 */
public class Client_Strategy {


    public static void main(String[] args) {
        doStrategy("A");
        doStrategy("B");
        doStrategy("C");
    }

    public static void doStrategy(String options){
        Context context = null;
        switch (options){
            case "A":
                context = new Context(new ConcreteStrategyA());
                context.ContextInterface();
                break;
            case "B":
                context = new Context(new ConcreteStrategyB());
                context.ContextInterface();
                break;
            case "C":
                context = new Context(new ConcreteStrategyC());
                context.ContextInterface();
                break;
        }
    }
}

运行结果如下:

这是算法A
这是算法B
这是算法C

5、分析

可以看出,使用策略模式,当有一个新的算法需求时,只需再增加一个新的算法实现类,更新下client端的选择即可,不会对原有的算法造成影响。

同时,我们可以很明显的看出,客户端做了很多的判断,这样的程序对客户端是不友好的。下面我们对context进行改造,结合“简单工厂”模式,写出更优的程序。

三、策略模式与简单工厂结合

1、改造后的context

package com.mfc.design.策略模式;

/**
 * @author MouFangCai
 * @date 2019/10/11 11:32
 */
public class Context_Factory {


    Strategy strategy = null;

    public Context_Factory(String options) {
        // 初始化时,根据客户端不同的选择,实例化具体的策略对象
        switch (options){
            case "A":
                strategy = new ConcreteStrategyA();
                break;
            case "B":
                strategy = new ConcreteStrategyB();
                break;
            case "C":
                strategy = new ConcreteStrategyC();
                break;
        }
    }

    // 上下文接口
    public void ContextInterface() {
        // 根据具体的策略对象,调用就其算法的方法
        strategy.algorithmInterface();
    }
}

2、改造后的客户端

package com.mfc.design.策略模式;

/**
 * @author MouFangCai
 * @date 2019/10/11 11:36
 */
public class Client_Strategy_Factory {


    public static void main(String[] args) {
        String options =  "A";
        Context_Factory a = new Context_Factory(options);
        a.ContextInterface();
    }

}

可以看到,使用“简单工厂”+ “策略模式” 后,客户端代码更加简洁。同时也使得具体的算法彻底与客户端分离,连算法的父类Strategy都不让客户端认识了。

简单工厂模式,请阅读参考https://blog.csdn.net/qq_36095679/article/details/89256921

 

标签:11,策略,模式,算法,Context,new,public,原来如此
来源: https://www.cnblogs.com/moufangcai/p/11654222.html