背景
策略模式是一种比较简单的设计模式,生活中做成一件事有几种不同的策略选择供你达成。比如你上班可以选择坐公交上班,可以选择坐地铁上班,也可以选择自驾上班,甚至还可以步行上班。
如果需要用代码表示上面的内容,你可以使用多重条件语句实现。
if("1".equals(status)) {
return "公交";
} else if("2".equals(status)) {
return "地铁";
} else if("3".equals(status)) {
return "自驾";
} else if("4".equals(status)) {
return "步行";
}
但是上面这样的代码实际就是硬编码,如果需要增加、移除、修改算法,需要在这里修改,违反了开闭原则。这个问题可以使用策略模式解决。
如果使用if语句,大概是这样的一个流程图:
if语句
使用策略模式的流程图:
策略模式
什么是策略模式
“Define a family of algorithms,encapsulate each one,and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。)
”
将算法调用方与算法实现方分割开来,实现两者之间的解耦。
策略模式的主要组成要素如下:
“”
抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
环境(Context)类:持有一个策略类的引用,最终给客户端调用。
代码实现
How2WorkStrategy
抽象策略类
interface How2WorkStrategy {
String how2WorkFun();
}
SubwayStrategy
地铁策略类
public class SubwayStrategy implements How2WorkStrategy{
@Override
public String how2WorkFun() {
return "地铁";
}
}
CarStrategy
自驾小车策略类
public class CarStrategy implements How2WorkStrategy{
@Override
public String how2WorkFun() {
return "自驾";
}
}
BusStrategy
公交车策略类
public class BusStrategy implements How2WorkStrategy{
@Override
public String how2WorkFun() {
return "公交";
}
}
WalkStrategy
步行策略类
public class WalkStrategy implements How2WorkStrategy{
@Override
public String how2WorkFun() {
return "步行";
}
}
Context
装载类,可理解为策略工厂。
public class Context {
public How2WorkStrategy getHow2WorkStrategy() {
return how2WorkStrategy;
}
public void setHow2WorkStrategy(How2WorkStrategy how2WorkStrategy) {
this.how2WorkStrategy = how2WorkStrategy;
}
private How2WorkStrategy how2WorkStrategy;
public String how2Work() {
return how2WorkStrategy.how2WorkFun();
}
}
测试代码:
@org.junit.Test
public void test() {
Context context = new Context();
How2WorkStrategy how2WorkStrategy = new CarStrategy();
context.setHow2WorkStrategy(how2WorkStrategy);
String s = context.how2Work();
Console.log(s);
Console.log("---------------------");
how2WorkStrategy = new BusStrategy();
context.setHow2WorkStrategy(how2WorkStrategy);
String s1 = context.how2Work();
Console.log(s1);
}
我们选择自驾策略和公交车策略,测试结果如下:
自驾
---------------------
公交
上面代码还有缺限,上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则是相违背的,我只是想使用了一个策略,我凭什么就要了解这个策略呢?那要你的封装类还有什么意义?这是原装策略模式的一个缺点,幸运的是,我们可以使用其他模式来修正这个缺陷,如工厂方法模式、代理模式或享元模式。
关于改进方法,有兴趣的还可以看看我的这篇文章:
“ ”
关于策略模式的思考
策略模式比较简单,如果存在多重if语句。并且if语句还有可能变化,那么我们就可以将if语句中的算法封装到类中,使用策略模式代替if语句。
总之策略模式就是:算法可自由切换、避免多重if-else语句、更好的扩展性。
往期推荐
扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料
1.回复"java" 获取java电子书;
2.回复"python"获取python电子书;
3.回复"算法"获取算法电子书;
4.回复"大数据"获取大数据电子书;
5.回复"spring"获取SpringBoot的学习视频。
6.回复"面试"获取一线大厂面试资料
7.回复"进阶之路"获取Java进阶之路的思维导图
8.回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)
9.回复"总结"获取Java后端面试经验总结PDF版
10.回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)
11.回复"并发导图"获取Java并发编程思维导图(xmind终极版)
另:点击【我的福利】有更多惊喜哦。