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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏魂祭心

原 What Every Dev need

29780
来自专栏MyBlog

Effective.Java 读书笔记(2)使用Builder

静态工厂和构造器都有一个限制,它们不能够很好地缩减大量地选项参数,想象一下一种情况,你的类有着很多的成员变量,有些必须填写有些可以选填,那么如果使用传统的构造方...

8220
来自专栏小灰灰

Java并发之 volatile & synchronized & ThreadLocal 讲解

Java 之 volatile & synchronized & ThreadLocal 讲解 在并发编程中,基本上离不开这三个东西,如何实现多线程之间的数据...

27960
来自专栏熊二哥

快速入门系列--CLR--03泛型集合

.NET中的泛型集合 在这里主要介绍常见的泛型集合,很多时候其并发时的线程安全性常常令我们担忧。因而简述下.NET并发时线程安全特性,其详情请见MSDN。 ...

18870
来自专栏java工会

Spring中的9种设计模式汇总

又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。

11310
来自专栏大内老A

ASP.NET MVC的Model元数据与Model模板:模板的获取与执行策略

当我们调用HtmlHelper或者HtmlHelper<TModel>的模板方法对整个Model或者Model的某个数据成员以某种模式(显示模式或者编辑模式)进...

21760
来自专栏Java编程技术

常用开源框架中设计模式使用分析- 装饰器模式(Decorator Pattern)

装饰器模式是一种结构性模式,它作用是对对象已有功能进行增强,但是不改变原有对象结构。这避免了通过继承方式进行功能扩充导致的类体系臃肿。

16310
来自专栏python3

python 装饰器案例解析

执行的时候,不能写deco(test1()),为什么呢?这样写,是把test1函数执行的结果,传给deco了。

9010
来自专栏Android相关

X86 Assemble指令--MOVS指令簇

该指令簇包括: MOVS mem16,mem16:显式指定源操作数与目的操作数 MOVSB:每次移动一个字节 MOVSW:每次移动一个字 MOVSD:每...

16320
来自专栏小狼的世界

Linux下不同文件编码的转换

字符编码(Character Encoding)可以说就是让某一字符序列匹配一个指定集合中的某一东西,常见的例子包括长短电键组合起来表示的摩斯电码(Morse ...

12320

扫码关注云+社区

领取腾讯云代金券