文章参考于《设计模式的艺术之道》——刘伟
前言:实现某一个功能有多条途径,每条途径对应着一种算法。如外出旅行,出行方式,便宜,时间无所谓的选择火车,时间赶,费用无所谓的选择飞机等等多种方式。
策略模式灵活地选择解决途径,也方便增加新的途径。
Context:环境类,使用算法的角色,在解决某个问题是有多种策略,并且在类中有一个抽象策略类的引用,来定义采用的策略。
Strategy:抽象策略类,可以是抽象类或具体类,也可以是接口。用于声明抽象方法。
ConcreteStrategy:具体策略类,实现抽象策略类的方法,或者覆盖,一种具体的算法实现。
代码的实现
//抽象策略类
abstract class AbstractStrategy {
//声明抽象方法
public abstract void algorithm();
}
//具体的策略类,ConcreteStrategyB类似,封装着具体的算法
class ConcreteStrategyA extends AbstractStrategy {
//算法具体实现
public void algorithm() {
//算法A
}
}
//环境类,与抽象策略类建立关联关系
class Context{
//对抽象策略类的引用
private AbstractStrategy strategy;
public void setStrategy(AbstractStrategy strategy) {
this.strategy = strategy;
}
//调用策略类的算法
public void algorithm() {
strategy.algorithm();
}
}
在Java中用到策略模式的例子
JavaSE的容器布局管理,设置自己想要的布局BorderLayout、FlowLayout等等
//Container类的代码片段
public class Container extends Component {
//....
LayoutManager layoutMgr;
//....
public void setLayout(LayoutManager layoutMgr) {
this.layoutMgr = layoutMgr;
//....
}
//....
}
从代码中可以看出,Container作为环境类,针对抽象策略类LayoutManager进行编程,用户使用时,只需要根据里氏代换原则,在setLayout()方法中传入具体想要的布局对象即可,无须关心该布局对象的具体实现。
总结
优点:
①增添一个其他的实现算法,符合开闭原则。
②避免了算法选择的多重条件选择语句。
③策略类是独立的,可以在不同的环境类下复用。
缺点:
①客户端需要了解算法的区别,才能更适合的选择恰当的算法。
②产生了很多的具体策略类。