zoukankan      html  css  js  c++  java
  • 设计模式——策略模式

    一、定义与简单实现

    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

  • 相关阅读:
    se 键盘鼠标操作事件
    警告框操作方法(alert弹窗)
    se自带截图方法
    CSS Selector 高级用法
    吃奶酪
    互不侵犯
    hdu1102
    P4744 Iron man
    玉米田
    状压dp题单
  • 原文地址:https://www.cnblogs.com/wqff-biubiu/p/12613936.html
Copyright © 2011-2022 走看看