策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得他们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
角色:
-
Context角色:持有一个 Strategy 的引用
-
抽象策略(IStrategy)角色:这是一个抽象角色,通常是一个接口或者是抽象类,此角色给出所有的具体策略类所需要的接口
-
具体的策略角色(Strategy):实现了抽象策略角色,包装了具体实现的算法或行为
-
策略的调用者:创建了 context 对象,调用其所持有的 Strategy 的引用
类图如下:
应用场景实例:
-
诸葛亮的锦囊妙计,每一个锦囊就是一个策略
-
出行方式,选择骑自行车、坐汽车等,每一种方式都是一种策略
何时使用:一个系统中有许多许多类,而区分它们的只是它们直接的行为
具体代码实现:
-
创建策略的接口IStrategy
package com.acmen.Strategy_pattern; /** * 策略的接口IStrategy,即策略的提供者 */ public interface IStrategy { //每一个策略都有一个可执行的算法 public void operate(); }
-
创建策略的具体实现类StrategyA、StrategyB、StrategyC
StrategyA的具体类:
package com.acmen.Strategy_pattern; /** * This is StrategyA. */ public class StrategyA implements IStrategy { @Override public void operate(){ System.out.println("This is StrategyA's strategy...."); } }
StrategyB的具体类:
package com.acmen.Strategy_pattern; /** * This is StrategyB. */ public class StrategyB implements IStrategy { @Override public void operate(){ System.out.println("This is StrategyB's strategy...."); } }
StrategyC的具体类:
package com.acmen.Strategy_pattern; /** * This is StrategyC. */ public class StrategyC implements IStrategy { @Override public void operate(){ System.out.println("This is StrategyC's strategy...."); } }
-
创建Context角色
package com.acmen.Strategy_pattern; /** * 这是策略的承载者,即载体 */ public class Context { //通过构造函数确定要使用的具体策略 private IStrategy strategy; public Context(IStrategy strategy){ this.strategy = strategy; } //执行具体的策略里的算法 public void operate(){ strategy.operate(); } }
-
创建策略的调用者进行调用
package com.acmen.Strategy_pattern; /** * 策略模式: * 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。 * 策略对象改变 context 对象的执行算法。 * * 要素说明:要有多个策略,策略的载体,策略的调用者,策略的提供者 * * 这个类是策略的调用者 */ public class Main { public static void main(String[] args) { //获得承载策略的载体Context,通过构造方法明确要使用的策略 Context context; System.out.println("Use strategyA..."); context = new Context(new StrategyA()); context.operate(); System.out.println("Use strategyB..."); context = new Context(new StrategyB()); context.operate(); System.out.println("Use strategyC..."); context = new Context(new StrategyC()); context.operate(); } }
策略模式的优点:
-
算法可以自由切换。
-
避免使用多重条件判断
-
扩展性良好
策略模式缺点:
-
策略类会增多
-
所有策略类都需要对外暴露
-