zoukankan      html  css  js  c++  java
  • 【小知识】小例子说明Spring的核心思想之一:控制反转。

    装饰设计模式:使用频率很高!!!

      目的:改写已存在的类的某个方法或某些方法,使方法增强了。装饰设计模式(也即包装设计模式)
      口诀:

        1、编写一个类,实现与被包装类相同的接口。(这样他们就具备了相同的行为
        2、定义一个被包装类类型的变量,即引用,用于接收被包装的对象。
        3、定义构造方法,把被包装类的对象注入,给被包装类变量赋值。(因为后面我要用该包装类的对象,所以要注入进来
        4、对于需要改写的方法,写自己的代码。(若重写方法的时候,还需要用到其他类的对象,那我们就在构造方法中继续注入即可)
        5、对于不需要改写的方法,使用被包装类对象调用原有的方法。

      示例代码如下:

    // 注意:该类本身就是一个装饰类,对原类的具体装饰饰在该类中实现。(但是需要写很多多余的代码)
    public class MyConnection implements java.sql.Connection // 1、编写一个类,实现与被包装类相同的接口。(具备相同的行为)

        // 2、定义一个被包装类类型的变量,即引用,用于接收被包装的对象。
        private java.sql.Connection conn; // 同时也是要注入的东西

        // 定义我们缺的池子
        private List<Connection> pool; // 这是我们缺的池子

        // 3、定义构造方法,把被包装类的对象注入,给被包装类变量赋值。也把我们需要的池子给注入。
        // 注入的对象可以是com.mysql.jdbc.Connection,也可以是com.oracle.jdbc.Connection,即不同的控制权
        public MyConnection(com.mysql.jdbc.Connection conn, List<Connection> pool) // 对被包装的对象和池子进行构造初始化
            this.conn = conn;
            this.pool = pool;
        }

        // 4、对于需要改写的方法,写自己的代码。
        @Override
        public void close() throws SQLException {
            pool.addLast(conn); // 还回数据库连接池中,但是呢我们缺少池子,那么我们就要注入一个池子(依赖注入)
        }

        // 5、对于不需要改写的方法,使用被包装类对象调用原有的方法。注意:不需要改写代码有很多啊!省略了。
        @Override // 以下有很多,比如:
        public void submit() {
            conn.submit(); // conn就是我们注入的对象
        }

        @Override
        public PreparedStatement prepareStatement(String sql) throws SQLException {
            return conn.preparedStatement(sql); // conn就是我们注入的对象
        }

        @Override
        // ......
    }

      上面的例子有一个Spring的核心思想:控制反转。作用:降低耦合
        实现方式一:使用依赖注入。(很常用)什么是依赖注入呢?答:就是缺什么传什么。上面的例子中,开始的控制权在接口,后来你注入的是什么,控制权就是谁了。即控制反转,控制权发生了转移。
        实现方式二:使用依赖查找。(不常用)

    默认适配器模式:是装饰设计模式的一个变体(针对上面不好的地方进行改进)

      目的:由于不需要改写代码有很多,而需要改写的代码虽然很少,但是老是在改动,这样代码的可维护性差、健壮性不好,好的代码就是:不是总要修改的代码放在一起,只写一次就行,而把需要经常修改的代码放在一起,你想改就改。

      口诀:

        1、编写一个类,实现与被包装类相同的接口。(这样他们就具备了相同的行为
        2、定义一个被包装类类型的变量,即引用,用于接收被包装的对象。
        3、定义构造方法,把被包装类的对象注入,给被包装类变量赋值。(因为后面我要用该包装类的对象,所以要注入进来
        4、对于不需要改写的方法,使用包装类对象调用原有的方法。

    示例代码如下:

      包装适配器类代码:

    // 该类本身也是一个装饰类,只是对原类没有任何装饰而已,具体的装饰在具体的装饰实现类中。(即对原类没有任何改变。)
    public class MyConnectionWarper implements Connection {

        private Connection conn;

        public MyConnectionWarper(Connection conn) {
            this.conn = conn;
        }

        @Override
        public <T> unwrap(Class<T> iface) throws SQLException {
            return conn.unwrap(iface);
        }

        @Override
        public boolean isWrapperFor(Class<?> iface) throws SQLException {
            return conn.isWrapperFor(iface);
        }

        @Override
        public Statement createStatement() throws SQLException {
            return conn.createStatement();
        }

        @Override
      //......
    }

      包装适配器实现类代码:

    public class MyConnection extends MyConnectionWarper {

        private Connection conn;
        private LinkedList<Connection> pool;

        public MyConnection(Connection conn, LinkedList<Connection> pool) {
            super(conn);
            this.conn = conn;
            this.pool = pool;
        }

        @Override
        public void close() throws SQLException {
            pool.addLast(conn);
        }
    }

    参考链接:https://www.cnblogs.com/chenmingjun/p/9027118.html

  • 相关阅读:
    LeetCode 42. Trapping Rain Water
    LeetCode 209. Minimum Size Subarray Sum
    LeetCode 50. Pow(x, n)
    LeetCode 80. Remove Duplicates from Sorted Array II
    Window10 激活
    Premiere 关键帧缩放
    AE 「酷酷的藤」特效字幕制作方法
    51Talk第一天 培训系列1
    Premiere 视频转场
    Premiere 暴徒生活Thug Life
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/9262576.html
Copyright © 2011-2022 走看看