策略模式是一种比较简单的设计模式,生活中做成一件事有几种不同的策略选择供你达成。比如你上班可以选择坐公交上班,可以选择坐地铁上班,也可以选择自驾上班,甚至还可以步行上班。
如果需要用代码表示上面的内容,你可以使用多重条件语句实现。
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.(定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。) ”
将算法调用方与算法实现方分割开来,实现两者之间的解耦。
策略模式的主要组成要素如下:
抽象策略类
interface How2WorkStrategy {
String how2WorkFun();
}
地铁策略类
public class SubwayStrategy implements How2WorkStrategy{
@Override
public String how2WorkFun() {
return "地铁";
}
}
自驾小车策略类
public class CarStrategy implements How2WorkStrategy{
@Override
public String how2WorkFun() {
return "自驾";
}
}
公交车策略类
public class BusStrategy implements How2WorkStrategy{
@Override
public String how2WorkFun() {
return "公交";
}
}
步行策略类
public class WalkStrategy implements How2WorkStrategy{
@Override
public String how2WorkFun() {
return "步行";
}
}
装载类,可理解为策略工厂。
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语句、更好的扩展性。