前言
- 每天这个点,带了一天的隐形眼睛,看电脑实在有点疲劳了,不过当我看到这个策略模式简介的时候,我一下来了精神.
- 我相信很多初级程序员想在代码质量上有所提升的时候,我们会发现我没之前封装的一些方法类,是否过于冗余??如果有新的需求,我们是否是直接在该类里面直接创建一个新的方法,不断使这个类变得臃肿,难以维护.
- 其实策略模式总结起来还是java接口的善用,java特性抽象\封装\继承\多态也在该模式有良好的体现.
定义
- 定义:策略模式定义了一系列的算法,并将每个算法封装起来,而且使他们还可以相互替换.看上去有点难以理解,没关系,等下我们看下他的UML类图就一下清晰了.
- 优点:
1.结构清晰明了,使用简单直观.
2.耦合度相对较低,扩展方便.
3.操作封装也更为彻底,数据更为安全. - 缺点:随着策略的增加,子类也会变得繁多.
- 使用场景:(也就是我们一般封装的control类,实现具体业务逻辑的类)
1.针对同一类型问题的多种处理方式,仅仅是具体行为有所差别的时候.
2.需要安全的封装多种同一类型的操作.
3.出现同一抽象类,有多个子类,而且又需要使用if-else或者switch-case来选择具体子类的时候.
UML类图
- 根据这幅UML类图,第一次接触策略模式的你,是否一下思路就清晰了
- Context: 操作策略的上下文,跟策略是一对多的关系.
- Stragety:策略的抽象类
- ConcreteStragetyA:具体的明确策略子类实现
实现步骤
- 根据书上提供的案例,我们根据实际业务需求,把业务方法做成接口,需要返回不同类别的方法,分别作为类去实现该接口
- 接下来是我们的demo目录截图
- 我们先来看看,很容易就常规的写法,作为对比:
/**
* 原始封装的工具类,用来封装计算交通价格
* 分别是公交\地铁\出租车封装的计算出行费用
* 也是我们通常的书写习惯,比如一个单一职责的类,内部有不同的方法
* @author max
*
*/
public class PriceCalculator {
public static final int BUS = 1; //公交
public static final int SUBWAY = 2; //地铁
public static final int TEXI = 3; //出租车
/**
* 计算公交车出行价格
*/
private int busPrice(int km){
//中间计算过程就省略了,
int priceBus = 0;
return priceBus;
}
/**
* 计算地铁出行价格
*/
private int subwayPrice(int km){
//中间计算过程就省略了,
int priceSubway = 0;
return priceSubway;
}
/**
* 计算出租车出行价格
*/
private int texiPrice(int km){
//中间计算过程就省略了,
int priceTEXI = 0;
return priceTEXI;
}
//还需对外暴露这个方法,调用
public int calculatePrice(int km , int type){
if (type == BUS) {
return busPrice(km);
}else if (type == SUBWAY) {
return subwayPrice(km);
}else if (type == TEXI) {
return texiPrice(km);
}
return 0;
}
}
- 这里就贴主要代码吧.
- Stragety:把业务方法做成接口,这里用书上的demo,就是计算交通工具费用,
/**
* 计算接口
* 每一个种类的出行方式都单独写一个类,来实现本接口的方法
* 因此弊端也很明显--随着策略的增加,子类也会变得繁多
* @author max
*
*/
public interface CalculateStrategy {
int calculatePrice(int km);
}
- ConcreteStragetyA:接下来,如UML类图所示,就是具体的明确策略子类实现,这里就列举一个吧,其他都类似,具体的业务逻辑,根据实际需求在相应类里面写,
/**
* 计算地铁价格 具体策略类
*
* @author max
*/
public class SubwayStrategy implements CalculateStrategy {
@Override
public int calculatePrice(int km) {
// 中间计算过程就省略了,
int priceSubway = 0;
return priceSubway;
}
}
- Context: 最后一步,就是上下文调用策略类,实现具体逻辑
private CalculateStrategy mStrategy;
// 策略模式的计算方式调用
private void strategyCalculate() {
setStrategy(new TexiStrategy());
int price = calculatePrice(16);
}
public void setStrategy(CalculateStrategy strategy) {
this.mStrategy = strategy;
}
public int calculatePrice(int km) {
return mStrategy.calculatePrice(km);
}
源码下载
- 如果用接口的话,是不是要比写一个单独的工具类要来的方便的多,避免了工具类过于冗余,和维护起来不方便.其实对比来看,策略模式也就是把公共的方法封装成接口来实现,http://download.csdn.net/detail/qq_28690547/9437854