策略模式是使用面向对象的继承和多态思想,将同一接口的不同算法实现封装在不同的类中,从而使他们相互替换,达到客户端环境不受算法变动的影响,降低耦合。
策略模式(StrategyPattern)也成政策模式,通过定义抽象类或基类的策略,来生成不同实现的算法家族,以便各个具体策略类(ConcreteStrategy)能够进行替换,降低耦合。
策略类的组成角色:
- 环境类(Context):持有一个Strategy的引用。
- 抽象策略类(Strategy):这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(ConcreteStrategy):具体的算法或行为实现。
实例代码:
策略类
abstract class Strategy {
/**
* 定义通用策略,开启唤醒。
*/
public abstract void startWake();
}
class GlobalStrategy extends Strategy {
@Override
public void startWake() {
System.out.print("global strategy");
}
}
class TelephoneStrategy extends Strategy{
@Override
public void startWake() {
System.out.print("telephone strategy");
}
}
Context环境类
public class Context {
private Strategy strategy;
/**
* 调用不同的策略进行执行
* @param strategy
*/
public void startWake(Strategy strategy){
strategy.startWake();
}
}
客户端
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
Strategy strategy = new GlobalStrategy();
Context context = new Context();
context.startWake(strategy);
}
}
策略模式优缺点
优点
策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
缺点
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。