“策略模式”原来如此简单
作者:互联网
一、策略模式简介
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