• 【小知识】小例子说明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

  • 相关阅读:
    线程池的实现原理
    log4j 具体解说(不能再具体了)
    MyEclipse中背景颜色的设定
    cacheManager载入问题
    SAP 经常使用T-CODE
    Oracle 版本号说明
    用XMPP实现完整Android聊天项目
    选择如何的系统更能适合App软件开发人员?
    爱国者布局智能硬件,空探系列PM2.5检測仪“嗅霾狗”大曝光
    Innodb引擎状态查看
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/9262576.html
Copyright © 2020-2023  润新知