通过连接池操作 理解装饰者设计模式 自我理解

装饰者设计模式:用于数据库连接中close方法的增强

自我理解:装饰者设计模式的方法增强,就是自定义一个类去实现我们需要增强的方法的接口,并定义一个成员变量对象去存储我们之前的对象,
那么这个成员变量所有调用的方法就是我们原来接口中的方法,因为成员变量对象 是我们原来对象的副本,然后改写我们要增强的方法即可。

应用:
当我们创建数据库连接池中连接时, 当我们用完我们创建的连接需要将连接放回到连接池(此处用集合模拟连接池)时,
此时Connection类中的close方法不能够满足我们的需求, 因为他是关闭连接,不是放回到连接池,
所以我们就想增强一下他的close方法,将这个方法重写为当在连接池中调用close方法关闭连接时,我们将这个连接放回到连接池,
此时我们就用到了装饰者设计模式。

自我理解:如果需要在增强后,真正的关闭连接 那么我们需要自定义方法去获取我们增强版的类的成员变量对象,因为这个对象就是原来的对象,再用他去调用我们增强类实现的接口里面的方法,就可达到目的(其实就是将原来对象用副本对象代替执行原有的方法)

实际代码:
Connection conn = DriverManager...
MyConnection myConn = new MyConnection(conn);
myConn.close();//此方法增强了
myConn.commit();//底层调用C类具体方法,conn.commit()
连接池中之后使用都是MyConnection , pool.add(myConn)

步骤:
1.必须实现接口A
2.提供有参构造,参数类型为接口A
3.提供成员变量,存放构造方法接口实际参数(其他实现类)
4.实现需要增强的方法
5.实现不需要增强的方法,调用成员变量对应的方法即可


/** 目的:使用装饰者设计模式,对Connection接口的close方法进行增强。
 * 装饰者设计模式固定的步骤:
 * 接口A,自定义实现B,其他实现类C
 * * 模式
 *     A a = C (工具类)
 *     B b = new B(a);
 * * 实际代码
 * Connection conn = DriverManager....
 * MyConnection myConn = new MyConnection( conn );
 * myConn.close();        //此方法增强了
 * myConn.commit() ; //底层调用C类具体方法,conn.commit();
 * **连接池中之后使用都是MyConnection  ,pool.add(myConn);
 *
 * 1.必须实现接口A
 * 2.提供有参构造,参数类型为接口A
 * 3.提供成员变量,存放构造方法接口实际参数(其他实现类)
 * 4.实现需要增强的方法
 * 5.实现不需要增强的方法,调用成员变量对应的方法即可。
 *
 */
public class MyConnection2 implements Connection {
    
    private Connection conn;
    private List<Connection> pool;
//    public MyConnection2(Connection conn){
//        this.conn = conn;
//    }
    public MyConnection2(Connection conn,List<Connection> pool){
        this.conn = conn;
        this.pool = pool;
    }
    
    //增强的方法--将当前连接归还给连接池
    @Override
    public void close() throws SQLException {
        //this 当前对象,表示当前连接
        pool.add(this);
    }
    //可以真实关闭
    public Connection getConnection(){
        return this.conn;
    }
    // 不增强的方法
    @Override
    public void commit() throws SQLException {
        this.conn.commit();
    }
    @Override
    public void rollback(Savepoint savepoint) throws SQLException {
        this.conn.rollback(savepoint);
    }
    
具体实现 包括真实关闭
/** 进行方法增强,对close方法进行增强。
 * 1.继承,子类复写父类的方法。必须明确父类(可以获得父类名称)。
 *     通过工具类DriverManager获得连接,无法确定父类。
 * 2.设计模式--装饰者,必须有接口【】
 *     设计模式:就是一段固定的代码,为了解决固定的问题。
 *     装饰者目的:增强方法
 * 3.动态代理,必须有接口
 * 4.字节码增强,增强指定类,不需要接口
 *
 */
public class MyPool4 {
    
    //1 容器 -- LinkedList --> 增删多,比较快
    private static LinkedList<Connection> pool = new LinkedList<Connection>();
    
    static{
        //1.1 初始化连接池,提供3个连接
        try {
            //1) 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            
            for(int i = 0 ; i < 3 ; i ++){
                //2) 获得连接
                Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ee30_day10", "root", "1234");
                // 将连接添加到池中
                //pool.add(conn);  //conn 提供连接的close存在缺陷,没有将连接归还给连接池
                //3)将已经增强close的MyConnection添加到连接池中
                MyConnection myConn = new MyConnection( conn , pool );
                pool.add(myConn);
            }
            
            //3) JVM 虚拟机关闭时,真实关闭连接
            Runtime.getRuntime().addShutdownHook(new Thread(){
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                        for(Connection myConn : pool){
                            if(myConn instanceof MyConnection){    //判断前面变量是否是后面指定类型
                                MyConnection my = (MyConnection) myConn;
                                System.out.println("真实关闭" + my);
                                my.getConnection().close();
                            }
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }

                }
            });
            
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    
    //2 获得连接,先判断池中是否有,如果有移除。否则等待100毫秒,递归
    public static Connection getConnection(){
        //有
        if(! pool.isEmpty()){
            return pool.removeFirst();
        }
        
        //没有
        try {
            Thread.sleep(100);
        } catch (Exception e) {
        }
        return getConnection();
    }
    
    //3 释放资源--将连接归还给连接池(添加到池中)
    public static void closeResource(Connection conn){
        //conn.close();  //真的关闭连接
        pool.add(conn);
    }
    

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值