從一個ConnectionPool的實現看design pattern的運用 (續六) (轉)

worldblog發表於2007-12-12
從一個ConnectionPool的實現看design pattern的運用 (續六) (轉)[@more@] 

這種Rellector的方法也有一點美中不足的地方,那就是,我們把我們在ResourceManImpl中使用.util.Collection的實現細節暴露給了ResourcesCollection。如果一個ResourceMan的實現者不想用Collection,那就不太容易了。:namespace prefix = o ns = "urn:schemas--com::office" />

你可以說,反正Collection是個interface, 我們可以讓那個ResourceMan的實現者寫一個adapter, 不就行了?

 

是啊。理論上是可以。但是,該死的Sun在Collection裡面定義了太多的方法。而一些方法竟然是optional的。也就是說,如果一個ResourcesCollector的實現者使用了某個optional方法,不會報錯。而如果一個ResourceMan的實現者使用的容器並不支援這些optional的方法,編譯器也不會報錯。但是,當你把兩者組裝起來的時候,通!OperationNotSupportedException!

 

哎,要定義一個既要滿足所有可能的ResourcesCollecor的要求 (如順序存取,隨機存取等等),又要讓所有可能的ResourceMan都能實現的容器的介面是太困難了!

我想,這種要求應該是無解的。因為,ResourceMan和ResourcesCollector之間並不是足夠松的耦合。概念上,ResourceMan必須選擇一種能夠符合ResourcesCollector的要求的容器。這就是它們之間需求上自然定義的耦合。所以,不存在一個可解除它們之間的耦合的完美解也就不值得驚訝了。

好在,ResourcesCollector只是ResourceMan功能的一個小子模組。它們之間如何組織並不影響我們整個pooling 。

 

 

下面,讓我總結一下我們的pooling的框架系統的結構:

1. 可重用的pooling邏輯:

ResourceMan:  實現純pooling演算法邏輯,對具體的資源種類保持最大的透明度。

ResourceFactory: 用來封裝資源生成邏輯,需要組合進ResourceMan.

ResourcesCollector: 用來封裝整組資源回收,需要組合進ResourceMan。

  ResourceCollector: 用來封裝個體資源回收,需要組合進ResourcesCollector.

2.

PooledConnection: 封裝Connection,使之與pool協調工作。

3.

ResourceMan2ConnectionPool: 類似於ConnectionMan2ConnectionPool, 負責使用PooledConnection來把一個不能對容錯,對使用者不透明的ResourceMan轉化成對使用者透明的ConnectionPool.

 

 

要實現一個ConnectionPool,

1。 我們先要找一個合適的pooling邏輯,也就是一個ResourceMan的實現類,

2。 然後, 根據資源的特性,決定使用哪一個ResourcesCollector. 比如,為ConnectionPool使用LinearResourcesCollector; 為thread 使用NopResourcesCollector.

3。因為Connection資源需要對單個資源進行釋放,把ConnectionCollector交給LinearResourceCollector

4。構造ResourceMan的物件例項。

5。 使用ResourceMan2ConnectionPool類把ResourceMan轉換為ConnectionPool. ResourceMan2ConnectionPool會使用PooledConnection進行封裝。

 

 

在以上的步驟中,還有一些共性可以提取。雖然使用者自己來選購ResourceMan 和ResourceConnection, 但對ConnectionPool來說,ResourcesCollector, ResourceCollector的實現都是固定的, ResourceMan2ConnectionPool也是固定使用的。

 

如果我們抽象這個過程, 可不可以是我們的使用者介面更加簡單呢?理想中,介面應該是這樣:

public interface ResourceManFactory{

  public ResourceMan getResourceMan(ResourceFactory factory, ResourcesCollector collector);

}

public class ConnectionPoolFactory{

public static ConnectionPool

  getConnectionPool(ResourceManFactory mf, ResourceFactory

  return mf.getResourceMan(rf,

    LinearResourcesCollector.instance(

    ConnectionCollector.instance()

)

  }

}

 

這樣,構造ConnectionPool的人,只需要選擇合適的ResourceManFactory 和ResourceFactory, 其它什麼都不用管了。不能再簡單了。

實現pooling 演算法的人,只需要研究他的演算法,其它什麼都不用管了。不能再簡單了。

實現ResourceFactory的人,只需要關注怎麼連線,其它什麼都不用管了。不能再簡單了。

一些橋接Connection和Resource的類都已經寫好了。不用管它們。

實現封裝Connection或其它Resource的人,只需要關注那個資源的介面和語義,做出適當對pool邏輯的調整,其它什麼都不用管了。不能再簡單了。

 

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991980/,如需轉載,請註明出處,否則將追究法律責任。

相關文章