1.UML
2.接口(抽象策略角色)
1 public interface IStratery {2 void operate();3 }
3.实现(具体策略角色)
1 public class BackDoor implements IStratery {2 @Override3 public void operate() {4 System.out.println("BackDoor -- 方法被执行");5 }6 }
1 public class GivenLight implements IStratery {2 @Override3 public void operate() {4 System.out.println("GivenLight -- 方法被执行");5 }6 }
1 public class BlockEnemy implements IStratery {2 @Override3 public void operate() {4 System.out.println("BlockEnemy -- 方法被执行");5 }6 }
4.策略类()
1 public class Context { 2 private IStratery iStratery; 3 4 public Context(IStratery iStratery) { 5 this.iStratery = iStratery; 6 } 7 8 public void operate() { 9 System.out.println("Context -- 方法被执行");10 this.iStratery.operate();11 }12 }
5.测试
1 public class Test { 2 public static void main(String[] args) { 3 Context context; 4 context = new Context(new BackDoor()); 5 context.operate(); 6 System.out.println("=================================================="); 7 context = new Context(new BlockEnemy()); 8 context.operate(); 9 System.out.println("==================================================");10 context = new Context(new GivenLight());11 context.operate();12 }13 }
6.结果
7.分析
7.1.应用场景
>. 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
>. 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
>. 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
7.2.优点
>. 策略模式提供了管理相关的算法族的办法. 策略类的等级结构定义了一个算法或行为族, 恰当使用继承可以把公共的代码移到父类内, 从而避免重复代码
>. 策略模式提供了可以替换继承关系的办法. 继承可以处理多种算法或行为. 如果不是用策略模式, 那么使用算法或行为的环境类就可能会有一些子类, 每一个子类提供一个不同的算法或行为. 但是, 这样一来算法或行为的使用者就和算法或行为本身混在一起. 决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起, 从而不可能再独立演化. 继承使得动态改变算法或行为变得不可能.
>. 使用策略模式可以避免使用多重条件转移语句. 多重转移语句不易维护, 它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起, 统统列在一个多重转移语句里面, 比使用继承的办法还要原始和落后.
7.3.缺点
>. 客户端必须知道所有的策略类, 并自行决定使用哪一个策略类. 这就意味着客户端必须理解这些算法的区别, 以便适时选择恰当的算法类. 换言之, 策略模式只适用于客户端知道所有的算法或行为的情况.
>. 策略模式造成很多的策略类, 每个具体策略类都会产生一个新类. 有时候可以通过把依赖于环境的状态保存到客户端里面, 而将策略类设计成可共享的, 这样策略类实例可以被不同客户端使用. 换言之, 可以使用享元模式来减少对象的数量.