• 设计模式——策略模式


    一、定义与简单实现

    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

  • 相关阅读:
    Sobel算子 (转)
    由矩阵运算来看初等矩阵的左乘右乘所影响到矩阵的行列变换的本质(转)
    矩阵的迹(转)
    深度神经网络识别图形图像的基本原理(转)
    图解卷积神经网络(二)(转)
    Matlab 的reshape函数(转)
    iOS关键词weak和assign的区别
    网络层HTPPS和HTTP的概念与区别
    iOS开发之#impor与#include的区别
    iOS制作自己的Framework框架
  • 原文地址:https://www.cnblogs.com/wqff-biubiu/p/12613936.html
Copyright © 2020-2023  润新知