策略模式,定义了一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。
策略模式中的角色:
(1) 抽象策略角色,抽象策略角色通常由一个接口或抽象类实现,定义公共的策略方法。
(2) 具体抽象角色,具体策略角色实现具体的策略算法,封装相关的算法和行为。
(3) 上下文环境角色,上下文环境角色中含有一个对具体策略对象实例的引用,最终供客户端应用程序调用。
现在考虑一种情景,一个人要出去旅游,他有多种交通方式可以选择,飞机、动车、大巴等等。这时选择不同的交通工具就是选择不同的策略。
类图:
代码实现:
抽象策略接口:
package com.demo.strategy.strategy;
public interface TravelStrategy {
public String travelMethod();
}
具体策略类:
package com.demo.strategy.strategy;
public class ByAirStrategy implements TravelStrategy {
@Override
public String travelMethod() {
return "By Air";
}
}
package com.demo.strategy.strategy;
public class ByTrainStrategy implements TravelStrategy {
@Override
public String travelMethod() {
return "By Train";
}
}
上下文环境:
package com.demo.strategy.context;
import com.demo.strategy.strategy.TravelStrategy;
public class Traveler {
private String name;
private TravelStrategy travelStrategy; // 策略
public void setTravelStrategy(TravelStrategy travelStrategy) {
this.travelStrategy = travelStrategy;
}
public Traveler(String name) {
this.name = name;
}
/*
* 根据当前策略执行相应的旅游方式
*/
public void travel() {
System.out.println(name + " travel " + travelStrategy.travelMethod());
}
}
测试代码:
package com.demo.strategy;
import com.demo.strategy.context.Traveler;
import com.demo.strategy.strategy.ByAirStrategy;
import com.demo.strategy.strategy.ByTrainStrategy;
public class MainApp {
public static void main(String[] args) {
Traveler huey = new Traveler("Huey");
huey.setTravelStrategy(new ByAirStrategy());
huey.travel();
Traveler sugar = new Traveler("Sugar");
sugar.setTravelStrategy(new ByTrainStrategy());
sugar.travel();
}
}
结果输出:
Huey travel By Air
Sugar travel By Train
使用策略模式的适用场合:
1) 当多个类的表现行为不同,需要在运行时动态选择具体要执行的行为的时候;
2) 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其他方式实现的时候;
3) 需要隐藏具体的策略(算法)的实现细节,各个具体策略(算法)彼此独立的时候;
4) 当一个类中出现了多种行为而且在一个操作中使用多个条件分支来判断使用多种行为的时候,可以使用策略模式将各个条件分支的动作植入具体的策略中实现。