策略模式(Strategy),定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。UML结构图如下:
其中,Context是上下文,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用;Strategy是策略类,用于定义所有支持算法的公共接口;ConcreteStrategy是具体策略类,封装了具体的算法或行为,继承于Strategy。
包含了三个角色:Context上下文,抽象策略角色,具体策略角色。
1. Context上下文
Context上下文角色,起到承上启下的作用,屏蔽高层模块对策略的直接访问,里面包含了抽象策略角色,通过构造方法转变成具体策略角色,之后就可以在上下文接口中使用具体策略角色的方法了。
public class Context { Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } //上下文接口 public void contextInterface() { strategy.algorithmInterface(); } }
2. 抽象策略角色
抽象策略角色,通常为接口,里面定义了每个策略必须具有的方法和属性。algorithm是“运算法则”的意思。
1 public abstract class Strategy {2 3 4 public abstract void algorithmInterface();5 6 }
3. 具体策略角色
具体策略角色需要继承抽象策略角色,用于实现抽象策略中的操作,即实现具体的算法,下方用print代替。测试类共3个ConcreteStrategy,其它两个类与ConcreteStrategyA同理。
1 public class ConcreteStrategyA extends Strategy {2 3 @Override4 public void algorithmInterface() {5 System.out.println("算法A实现");6 }7 8 }
4. Client客户端
下面依次更换策略,测试一下策略模式。
1 public class Client { 2 3 public static void main(String[] args) { 4 Context context; 5 6 context = new Context(new ConcreteStrategyA()); 7 context.contextInterface(); 8 9 context = new Context(new ConcreteStrategyB());10 context.contextInterface();11 12 context = new Context(new ConcreteStrategyC());13 context.contextInterface();14 }15 16 }
运行结果如下: