设计模式——策略模式

一、定义与简单实现

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

posted on 2020-04-01 17:15  FFStayF  阅读(495)  评论(0)    收藏  举报