從一個ConnectionPool的實現看design pattern的運用 (一) (轉)
從一個ConnectionPool的實現看design pattern的運用 (一):namespace prefix = o ns = "urn:schemas--com::office" />
什麼是ConnectionPool? 我們知道,JC提供了..Connection interface, 供我們連線不同的資料來源。但是,因為與建立連線是一個很大的開銷,所以,我們可以把已開啟的資料庫連線快取在一個連線池中,供後續的 Connection使用。使用者使用完Connection後,再把它返還到連線池中。
對一個連線池,有許多功能上的考慮。
1.如是否設定一個最大連線數,以保證資料庫不會因同時過多的連線請求而癱瘓;
2.是否設定一個最小連線數,以保證任何時刻都至少有若干個連線可用;
3.是否設定一個最多的空閒連線數,空閒連線超過這個數的就關閉過多的連線;
4.當對一個連線的請求不能被滿足時,是否讓請求同步等待,還是直接返回一個錯誤。
5.怎樣保證公平性,也就是說,一個對連線的同步請求會在一定的時間內得到x響應,而不是被餓死。
6.連線池是用vector, list還是其他的什麼Collection來實現。
等等等等。
下面,讓我們來看看一個ConnectionPool的實現:
public class ConnectionPool{
private final Vector pool = new Vector();
private int clients;
private int maxClients;
其他的一些連線屬性如username, pass, dsn等等;
public synchronized Connection getConnection(){
如果pool裡有Connection
從pool中去掉一個Connection conn;
clients++;
return conn;
否則,如果clients 生成一個新的連線conn clients++; return conn; 否則,wait(),直到pool中有空閒Connection } public synchronized void closeConnection(Connection conn){ pool.add(conn); clients--; notify(); } public synchronized void clear(){ for each connection in pool conn.close(); pool.removeAllElements(); } } 好了,讓我們來看一看有沒有什麼可以改善的。 首先,象我們剛開始所說的,對ConnectionPool的實現有許多不同的考慮,這個類明顯只是一個相當簡單的實現。那麼,我們是不是應該根據我們前面列出的條條,逐條進行實現呢? 不,如果那樣,我們就犯了過度設計的錯誤。也許我們現在並不需要那麼複雜的功能,為什麼要自找麻煩呢?而且,有些功能的取捨,並不是簡單的好與壞,是要根據具體的需要變化的。有些人也許會說,好吧,我在類裡放一些布林變數,對每種功能是否支援都可以configure. 這樣也許可行,但,你還是要對每個功能寫程式碼,最後這個ConnectionPool就變成一個spaghetti了。而且,夥計,讓我們謙虛一點吧!“不是我不明白,這世界變化快”,我們得承認,我們永遠也不可能預測所有的可能性。也不可能把所有的需求都實現到一個類中去。 那麼,我還“首先”什麼呢?反正也是先實現簡單的,“Simple and Stupid”。就這樣不是挺好嗎?問題是,我們要考慮使用我們ConnectionPool得使用者。雖然需求可能變化多端,但我們還是應該儘可能給使用者提供一個固定的介面。你不能這樣要求使用你的ConnectionPool的員:“喂,哥們兒,我昨天寫了一個ConnectionPool2, 比ConnectionPool酷多了,你改用這個吧。Replace All就行了”。 因此,我們應該把ConnectionPool設計成一個interface, 這樣,無論實現類如何變化,使用ConnectionPool interface的使用者可以不受影響。他們甚至可以根據需要使用不同的ConnectionPool的實現。簡單,是嗎?不就是一個interface嘛。相信我,你會看到它的作用有多大的。 其次,一個好的ConnectionPool應該是對Connection的使用者透明的。對一個使用Connection interface 的使用者,如: void doQuery(Connection conn){……} 它應該對該Connection是否來自ConnectionPool不敏感。 那麼,當不使用ConnectionPool時,我們怎麼釋放Connection呢?對了,是Connection.close(). 我們不應該要求使用者改調ConnectionPool.closeConnection來釋放Connection. 第三,假設我們有兩個ConnectionPool物件,一個連線資料庫,另一個連線. 現在,使用者同時使用兩個ConnectionPool, 當使用者使用完時,他不小心呼叫了sqlPool.closeConnection(orclConn); orclPool.closeConnection(sqlConn); 天啊!不定時炸彈!不要光埋怨程式設計師:“那種只知道依靠類庫的容錯性,沒有類庫的保護不知道怎麼的程式設計師不適合使用Java”。其實這完全是你的錯。 好了,預知後事如何,請聽下回分解。家庭作業是,請大家回去想想怎麼設計這個ConnectionPool。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991975/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 從一個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#
- 用Python實現一個實時運動的大掛鐘效果Python
- 用一個棧實現另一個棧的排序排序
- 從一個例子看Go的逃逸分析Go
- Design pattern 第一講 基礎知識
- 一個用C#實現的簡單http server (轉)C#HTTPServer
- 用java實現一個簡單的房屋管理程式。 (轉)Java
- 從另一個考慮來看程式碼的風格 (轉)
- 從一個安裝檔案看CGI的安全性 (轉)
- 從0搭建一個實用的MVVM框架MVVM框架
- 不太理解the design pattern java companion一書中的CommandJava
- 從0實現一個tiny react(一)React
- 用java實現一個簡單的序列化的例子(轉)Java
- 用java實現一個簡單的序列化的例子 (轉)Java
- STL and Design Pattern
- 用 go 實現一個簡單的 mvcGoMVC
- 從零實現一個 Webpack PluginWebPlugin
- 實現一個螺旋轉盤
- 原生js實現一個DIV的碰撞反彈運動JS
- React 實現一個簡單實用的 Form 元件ReactORM元件
- MySQL一主一從架構的實現MySql架構
- 微軟實現字串函式的一個BUG (轉)微軟字串函式
- 從原始碼看Spring中IOC容器的實現(一):介面體系原始碼Spring
- 從一道Promise執行順序的題目看Promise實現Promise
- Design Pattern理解碎片
- 用proxy實現一個更優雅的vueVue
- 用canvas實現一個簡單的畫板Canvas