首页 | 注册 | 登陆
首页 >> 技术专栏 >> java文章 >> java基础 

从一个ConnectionPool的实现看DesignPattern


作者java 来源java 加入时间:2006年03月19日
摘要:
从一个ConnectionPool的实现看DesignPattern
从一个ConnectionPool的实现看Design Pattern的运用 (五)
从一个ConnectionPool的实现看Design Pattern的运用 (五)

作者:ajoo

OK, 现在我们已经把封装Connection的任务从ConnectionPool的开发者身上去掉了。他们只要实现一个辅助的ConnectionMan 接口,余下的事由PooledConnection类和Connec…

转载:转载请保留本信息,本文来自
http://www.51dibs.com
/html/2006/article/info11/a_074ff84576e46872.htm




从一个ConnectionPool的实现看DesignPattern


站点:爱心种子小博士 关键字:从一个ConnectionPool的实现




从一个ConnectionPool的实现看Design Pattern的运用 (五)
从一个ConnectionPool的实现看Design Pattern的运用 (五)

作者:ajoo

OK, 现在我们已经把封装Connection的任务从ConnectionPool的开发者身上去掉了。他们只要实现一个辅助的ConnectionMan 接口,余下的事由PooledConnection类和ConnectionMan2ConnectionPool类来完成。
 
下面,再让我们仔细地看一下ConnectionManImpl类:
public class ConnectioManImpl implements ConnectionMan{
public synchronized Connection getConnection(){
    Connection ret;
        如果pool里有Connection
从pool中去掉一个Connection conn;
clients++;
ret = conn;
        否则,如果clients<maxClients
            conn = newConnection();
            clients++;
            ret = conn;
        否则,wait(),直到pool中有空闲Connection    
return conn;
    }
    public synchronized void closeConnection(Connection conn){
        pool.add(conn);
        clients--;
        notify();
}
private Connection newConnection(){
//使用用户名,密码,数据库url等等信息从DriverManager生成一个Connection
}
//必要的一些用户名,密码等建立connection的信息。
}
 
大家是否注意到了?ConnectionMan的实现者除了写pooling的算法,还要关心如何创建connection. 而这个创建connection的过程并不是总是一样的。我们可能从DriverManager生成Connection, 也可能从DataSource生成connection;可能用用户名,密码生成,也可能用connection string生成。
同样的pooling逻辑,可能需要处理不同的生成Connection的方式, 同一种生成connection的方式又有可能需要不同的pooling逻辑。因此,把pooling逻辑和connection生成耦合在一起似乎不是一个好办法。
 
那么如何解决这个问题呢?pooling算法中,确实需要在适当的时刻生成connection啊!
 
把ConnectionManImpl做成抽象类,然后要求每个子类覆盖newConnection()方法。 资深程序员张三不屑地说。
 
是啊,这确实是个直观又有效的方法。对同一个pooling算法,你只要subclass自己的子类,制定自己的connection生成,就可以重用父类的逻辑。这叫template method pattern.
 
不过,说实话,个人很不喜欢这个pattern. 从此例来说,假如我们有五种pooling算法,三种connection生成方法,那我们就需要写十五个子类。太不灵活了。而且,实现继承造成的父子类的强耦合关系,也是我所向来讨厌的。父类的某个不经心的改变,有可能就使子类不再工作。
 
那么。。。。
 
对啦!让我们抽象一下connection的生成吧。用abstract factory.
 
先定义一个factory的接口。
public interface ConnectionFactory{
    public Connection createConnection()throws SQLException;
}
然后改写我们的ConnectionManImpl, 让它把生成Connection的工作委托给一个ConnectionFactory.
 
Public class ConnectionManImpl implements ConnectionMan{
    Private final ConnectionFactory factory;
    Private final int maxConn;
    private ConnectionManImpl(ConnectionFactory factory, int max){
        this.factory = factory;
        this.maxConn = max;
    }
    static public ConnectionMan instance(ConnectionFactory factory, int max){
        return new ConnectionManImpl(factory, max);
    }
    public final synchronized Connection getConnection()
    throws SQLException
    {
        如果pool里有Connection
从pool中去掉一个Connection conn;
clients++;
return conn;
        否则,如果clients<maxClients
            conn = factory.createConnection();
            clients++;
            return conn;
        否则,wait(),直到pool中有空闲Connection    
    }
    //其他和前面一样。
}
 
再看一个示例ConnectionFactory的实现:
public class ConnectionFactoryImpl
{
    private ConnectionFactoryImpl(){}
    static public ConnectionFactory instance(final String user, final String pwd, 
        final String url, final String driver)
    throws SQLException, ClassNotFoundException{
        final Class driverClass = Class.forName(driver);
        return new ConnectionFactory(){
            private final Class keeper = driverClass;
            public final Connection createConnection()
            throws SQLException{
                return DriverManager.getConnection(url,user,pwd);
            }
        };
    }  
}
 
最后,再看看我们是怎样把一个ConnectionMan, 一个ConnectionFactory组合成一个ConnectionPool的。
 
public class TestConnectionPool{
    public static void test(String user, String pwd, String url, String driver)
    throws java.sql.SQLException, ClassNotFoundException{
        final ConnectionPool pool = ConnectionMan2ConnectionPool.decorate(
            ConnectionManImpl.instance(
                ConnectionFactoryImpl.instance(user, pwd, url, driver),
                1000)
            );
    }
}
 
 
好啦,这一章,我们显示了怎样把ConnectionManImpl中的pooling逻辑和Connection 生成的逻辑分开,从而实现更大程度上的代码重用。
 
思考题:
pooling, 作为一种技术,并不只是应用于ConnectionPool, 其他如Thread pool以及任何一种需要一定开销创建的资源都可以应用这种技术。
那么,我们怎样能够把一个pooling的算法重用给connection pool, thread pool等不同的pool呢?怎样才能说:给我李四写的pooling算法,我要拿它来对我的线程进行缓冲。?而不是说:李四,你的connection pooling算法写的不错,能不能给我的thread pooling也写一个一样的?






发布人:java
→ 推荐给我的好友 → 报告错误链接
上篇文章:从一个ConnectionPool的实现看Desig...
下篇文章:存储.properties文件的一个问题
〖文章打印〗
〖关闭窗口〗
发表评论
查看评论
中“从一个ConnectionPool的实现看DesignPattern”相关内容 中“从一个ConnectionPool的实现看DesignPattern”相关内容
中“从一个ConnectionPool的实现看DesignPattern”相关内容 中“从一个ConnectionPool的实现看DesignPattern”相关内容
中“从一个ConnectionPool的实现看DesignPattern”相关内容 中“从一个ConnectionPool的实现看DesignPattern”相关内容

关于我们网站留言友情链接与我在线与我聊天领取红包管理TOP