第六篇 编排方法 第十八章 - 策略模式
前文介绍的模板方法由若干抽象方法组合而成,抽象方法之间的关系主要是先后顺序关系。本章我们重点讨论方法之间的另一种关系——平行关系。
同一份功能可以用不同的方法(或算法)实现,这些方法构成了平行关系,彼此可以相互替代,使用时只择取其中一个。
怎么把一组平行的方法组织起来呢?
枚举(enum)是个不错的选择。
我们以小麦产量的预测方法为例进行说明。
// 产量预测方法
public enum Prediction {
// 湿法预测
WET {
@Override
public void predict() {}
},
// 干法预测
DRY {
@Override
public void predict() {}
};
public abstract void predict();
}
// 测试类
public class Test {
public void test() {
Prediction.WET.predict();
}
}
“湿法预测”和“干法预测”呈平行关系,把它们放在枚举中,这种关系显得一目了然。
大多数情况下,我们更希望将平行的方法分置在不同的类中,这样不仅很灵活,还会留出更多的扩展空间。策略模式就采用了这样的设计思路。
来看例子。
// 上下文
public class Context {
double m;// 单位面积穗数
double n;// 穗粒数
double t;// 千粒重
double w;// 风干后的单位面积重量
double s;// 种植面积
double p;// 产量
// 预测结果
public double result() {
return p;
}
}
// 策略
public interface Strategy {
public void predict(Context cxt);
}
// 湿法策略
public class WetStrategy implements Strategy {
public void predict(Context cxt) {
// 产量=单位面积穗数*穗粒数*千粒重*种植面积
}
}
// 干法策略
public class DryStrategy implements Strategy {
public void predict(Context cxt) {
// 产量=风干后的单位面积重量*种植面积
}
}
// 测试类
public class Test {
public void test() {
Context cxt = new Context();
Strategy obj = new WetStrategy();
obj.predict(cxt);
cxt.result();
}
}
两个产量预测方法升级成了“湿法策略”和“干法策略”两个类。方法之间的关系变得松散,各自有了更大的用武空间。连接它们的纽带是“策略”接口,这是一个冠名意义上的接口,方便大家将其实现类识别为一组呈平行关系的算法。
至此,两个方法之间的关系演变成了两个类之间的关系。
关于类之间关系的更多内容,我们将在最后一个篇目展开讨论。
浙公网安备 33010602011771号