一、定义与简单实现
1、定义
策略模式的定义包含三点:
- 定义一类算法(接口)。
- 封装每个算法(实现类)。
- 这类算法的算法可互相替换(实现类之间可互相替换)。
2、UML类图
前两点已经成了我们的职业习惯(项目中一般都是一接口对应一实现类),重点是要弄清楚后面的算法互相替换,这个替换是在哪里实现的,需要达到什么效果?下面是一个简单的策略模式的UML图。
- 定义一类算法(接口FlyBehavior)
- 封装每个算法(实现类CanFly + NotFly)
- Duck中定义一个FlyBehavior变量,然后运用组合的方式,CanFly、NotFly可以互换
定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户,使Duck与Fly()解耦,
运用的设计模式原则:
- 封装变化
- 多用组合,少用继承
- 针对接口编程,不针对实现编程
3、简单代码实现
/* * 飞翔行为 */ public interface FlyBehavior { void fly(); } public class CanFly implements FlyBehavior { @Override public void fly() { System.out.println("I can fly!"); } } public class NotFly implements FlyBehavior{ @Override public void fly() { System.out.println("I cant fly!"); } } /* * 叫声 */ public interface QuackBehavior { void quack(); } public class GaGa implements QuackBehavior{ @Override public void quack() { System.out.println("ga ga ..."); } } public class GuaGua implements QuackBehavior { @Override public void quack() { System.out.println("gua gua ..."); } } public class NotQuack implements QuackBehavior { @Override public void quack() { System.out.println("...... ??"); } } /* * 鸭子 */ public interface DuckInterface { void swim(); void display(); void performFly(); void performQuack(); void setFlyBehavior(FlyBehavior flyBehavior); void setQuackBehavior(QuackBehavior quackBehavior); } public class Duck implements DuckInterface { private FlyBehavior flyBehavior; private QuackBehavior quackBehavior; @Override public void swim() { System.out.println("I am swimming!"); } @Override public void display() { System.out.println("I have white feathers!"); } @Override public void performFly() { if (flyBehavior == null){ System.out.println("no flyBehavior!"); return; } flyBehavior.fly(); } @Override public void performQuack() { if (quackBehavior == null){ System.out.println("no quackBehavior!"); return; } quackBehavior.quack(); } @Override public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } @Override public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } } public class Main { public static void main(String[] args) { FlyBehavior canFly = new CanFly(); FlyBehavior notFly = new NotFly(); //一个会飞的鸭子 DuckInterface duck = new Duck(); duck.setFlyBehavior(canFly); duck.performFly(); //现在翅膀断了 duck.setFlyBehavior(notFly); duck.performFly(); } }
二、框架中的策略模式
框架中实现最明显的就是Mybatis中的执行器Executor,UML图
虽然与给出的标准的策略模式UML有所差异,但是实现的效果一致。
- 定义了一类一级缓存BaseExecutor(这里是个抽象类,由于方法有共同的逻辑,代码复用)
- 一级缓存BaseExecutor有多个具体的实现封装(SimpleExecutor、ReuseExecutor、BatchExecutor、ClosedExecutor)
- 二级缓存CachingExecutor中定义了一个一级缓存BaseExecutor变量(可用SimpleExecutor、ReuseExecutor、BatchExecutor互换,甚至可以用CachingExecutor互换,但是mybatis源码只是想达到前面的效果)
CachingExecutor的实例化:
/* org.apache.ibatis.session.Configuration#newExecutor(org.apache.ibatis.transaction.Transaction, org.apache.ibatis.session.ExecutorType) */ public Executor newExecutor(Transaction transaction, ExecutorType executorType) { executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor executor; if (ExecutorType.BATCH == executorType) { executor = new BatchExecutor(this, transaction); } else if (ExecutorType.REUSE == executorType) { executor = new ReuseExecutor(this, transaction); } else { executor = new SimpleExecutor(this, transaction); } if (cacheEnabled) {//默认为true executor = new CachingExecutor(executor); } executor = (Executor) interceptorChain.pluginAll(executor); return executor; }
1