设计模式之策略模式
其适用性:
许多相关的类仅仅是行为有异。“策略”提供了一种用于多个行为中的一个行为来配置一个类的方法,
需要使用一个算法的不同变体。例如,你可能会定义一些反应不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式,
算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构,
一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
其结构图:
Strategy定义了支持的算法的公共接口,如去出差去北京这件事情,ToBJ(),ConcreteStrategy类定义了具体的策略,如ByBus,ByCar,ByAirplane等,Context里维护对Strategy对象的引用,将客户的请求传递给Strategy,其与 Strategy的互相作用是通过选定的算法,当然也可以把Context传递给Strategy操作回调Context。
本文的实现和状态模式的实现类似,也不是在根据条件判断,而是直接传递过来一个Strategy实例回调Context。Context类指定一个Strategy实例:
package org.designpattern.behavioral.strategy;
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void doAction(){
this.strategy.algrithmInterface(this);
}
public void changeStrategy(Strategy strategy){
if(null != strategy){
this.strategy = strategy;
}
}
}
每个具体的Strategy子类,在实现时转变策略,直接把具体的策略当参数传递出去:
package org.designpattern.behavioral.strategy;
@Override
public void algrithmInterface(Context context) {
//To change body of implemented methods use File | Settings | File Templates.
System.out.println("doAction with strategyA!");
context.changeStrategy(new ConcreteStrategyB());
}
}
客户段测试类也很简单:
package org.designpattern.behavioral.strategy;
public static void main(String[] args) {
Strategy strategy = new ConcreteStrategyA();
Context ctx = new Context(strategy);
ctx.doAction(); //doAction with strategyA!
ctx.doAction(); //doAction with strategyB!
ctx.doAction(); //doAction with strategyA!
ctx.doAction(); //doAction with strategyB!
}
}
策略模式是定义一系列算法,把它们一个个封装起来,并且使它们可以相互转换,该模式使得算法可独立于它们客户端而变化。