從一個ConnectionPool的實現看design pattern的運用 (五) (轉)
從一個ConnectionPool的實現看design pattern的運用 (五):namespace prefix = o ns = "urn:schemas--com::office" />
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 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等等資訊從Manager生成一個Connection } //必要的一些使用者名稱,密碼等建立connection的資訊。 } 大家是否注意到了?ConnectionMan的實現者除了寫pooling的演算法,還要關心如何建立connection. 而這個建立connection的過程並不是總是一樣的。我們可能從DriverManager生成Connection, 也可能從Data生成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 Exception; } 然後改寫我們的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 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 .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也寫一個一樣的?”
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992488/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 從一個ConnectionPool的實現看design pattern的運用 (一) (轉)
- 從一個ConnectionPool的實現看design pattern的運用 (六) (轉)
- 從一個ConnectionPool的實現看design pattern的運用 (七) (轉)
- 從一個ConnectionPool的實現看design pattern的運用 (二) (轉)
- 從一個ConnectionPool的實現看design pattern的運用 (四) (轉)
- 從一個ConnectionPool的實現看design pattern的運用 (三) (轉)
- 從一個ConnectionPool的實現看design pattern的運用 (續六) (轉)
- 從一個ConnectionPool的實現看design pattern的運用 (source code for Java 1.1) (轉)Java
- aspectJ 實現design pattern
- 從編譯原理看一個直譯器的實現編譯原理
- Observer Design Pattern in C#! (轉)ServerC#
- 從五個SQL看with as使用SQL
- STL and Design Pattern
- 從SpringCloud看一個微服務框架的「五臟六腑」SpringGCCloud微服務框架
- 從零開始實現一個RPC框架(五)RPC框架
- 從一個群友問題看流複製實現原理
- 用Python實現一個實時運動的大掛鐘效果Python
- Design Pattern理解碎片
- 從 Spring Cloud 看一個微服務框架的「五臟六腑」SpringCloud微服務框架
- 從流程看企業營運(轉)
- 一個用C#實現的簡單http server (轉)C#HTTPServer
- 用java實現一個簡單的房屋管理程式。 (轉)Java
- 從另一個考慮來看程式碼的風格 (轉)
- 從一個安裝檔案看CGI的安全性 (轉)
- 從零開始實現一個簡易的Java MVC框架(五)–引入aspectj實現AOP切點JavaMVC框架
- 解構Core J2EE Pattern ――GoF Design Pattern的自然延伸Go
- Shell的五個小應用(轉)
- Design pattern 第一講 基礎知識
- 不太理解the design pattern java companion一書中的CommandJava
- 從一個例子看Go的逃逸分析Go
- [review]Design Pattern:CommandView
- 用java實現一個簡單的序列化的例子(轉)Java
- 用java實現一個簡單的序列化的例子 (轉)Java
- 從0搭建一個實用的MVVM框架MVVM框架
- 從零實現Vue的元件庫(五)- Breadcrumb 實現Vue元件
- 用一個棧實現另一個棧的排序排序
- 基於RabbitMQ.Client元件實現RabbitMQ可複用的 ConnectionPool(連線池)MQclient元件
- Node.js design pattern : moduleNode.js