看这个名字就知道对策略的分析的一种模式。什么是策略,从家里去上学可以选择走路、自行车、汽车、地铁,具体今天怎么去,就是策略的选择。
策略模式用于哪些场景呢?策略是将具体的算法分装成一个类,各个算法之间的使用相互并不影响,也有利于扩展,适用于算法经常在变动的,更换,替代的一类需求中。
下面用从家到学校的出行选择为例子:
首先分析下,从家到学校的出行方式有哪几种算法:
- 走路
- 自行车:公共自行车、私家山地车、电动自行车
- 汽车:公共汽车、私家车
- 地铁:地铁1号线、地铁2号线
/**
* 去学校的策略上下文
*/
public class ToSchoolContext {
private ToSchoolStrategy strategy = null;
public ToSchoolContext(ToSchoolStrategy strategy){
this.strategy = strategy;
}
/**
* 去学校的方式
*/
public void howToSchool(){
strategy.goWay();
}
}
下面对出行方式的算法的实现:
/**
* 走路去上学
*/
public class ToSchoolWalkStrategy extends ToSchoolStrategy {
@Override
public void goWay() {
System.out.println("走路去上学");
}
}
/**
* 骑车去上学
*/
public class ToSchoolBikeStrategy extends ToSchoolStrategy {
String bike;
public ToSchoolBikeStrategy(String bike) {
this.bike = bike;
}
@Override
public void goWay() {
System.out.println("骑" + bike + "去上学");
}
}
/**
* 乘车去上学
*/
public class ToSchoolCarStrategy extends ToSchoolStrategy {
String car;
public ToSchoolCarStrategy(String car) {
this.car = car;
}
@Override
public void goWay() {
System.out.println("乘" + car + "去上学");
}
}
/**
* 地铁去上学
*/
public class ToSchoolSubwayStrategy extends ToSchoolStrategy {
String line;
public ToSchoolSubwayStrategy(String line) {
this.line = line;
}
@Override
public void goWay() {
System.out.println("乘地铁" + line + "去上学");
}
}
以上就是算法的实现,下面说明怎么用:
public class Demo {
public static void main(String[] args) {
//周一选择走路
ToSchoolContext contextMonday = new ToSchoolContext(new ToSchoolWalkStrategy());
contextMonday.howToSchool();
//周二选择骑公共自行车
ToSchoolContext contextTuesday = new ToSchoolContext(new ToSchoolBikeStrategy("公共自行车"));
contextTuesday.howToSchool();
//周三选择公共汽车
ToSchoolContext contextWednesday = new ToSchoolContext(new ToSchoolCarStrategy("公共汽车"));
contextWednesday.howToSchool();
//周四选择地铁一号线
ToSchoolContext contextThursday = new ToSchoolContext(new ToSchoolSubwayStrategy("一号线"));
contextThursday.howToSchool();
}
}
如果还有其他的算法,如坐飞机,就添加相应的实现类。不会影响到其他的算法。
小改进
这样写,在真实项目中有几个问题,第一,我有多少总算法,我怎么选择?;第二,增加了耦合度,增加了客户端编程的复杂度。
试着和简单工厂模式的结合:
/**
* 去学校的策略上下文
*/
public class ToSchoolContext {
private ToSchoolStrategy strategy = null;
public ToSchoolContext(ToSchoolStrategy strategy) {
this.strategy = strategy;
}
public ToSchoolContext(String way) {
if ("走路".equals(way)) {
strategy = new ToSchoolWalkStrategy();
} else if ("公共自行车".equals(way)) {
strategy = new ToSchoolBikeStrategy("公共自行车");
} else if ("公共汽车".equals(way)) {
strategy = new ToSchoolCarStrategy("公共汽车");
} else if ("私家车".equals(way)) {
strategy = new ToSchoolCarStrategy("私家车");
} else if ("地铁一号线".equals(way)) {
strategy = new ToSchoolSubwayStrategy("一号线");
} else if ("地铁二号线".equals(way)) {
strategy = new ToSchoolSubwayStrategy("二号线");
}
}
/**
* 去学校的方式
*/
public void howToSchool() {
strategy.goWay();
}
}
屏蔽了客户端对ToSchoolStrategy的知道,只要能达成目的就行。