前些天擺弄java,參考一些資料寫了個資料庫連接池,對裡面只產生一個執行個體的那種做法深表佩服,今天中午又聽到別人在說設計模式,受不了了,就上網Down了點資料來。
一來就看到了Singleton模式,一看,呀,不就是那個串連池裡用的方法麼?!噢,原來如此。
Singleton 是一種建立性模型,它用來確保只產生一個執行個體,並提供一個訪問它的全域訪問點。
為了實現 Singleton 模式,我們需要一個靜態變數,能夠在不建立對象的情況下記憶是否已經產生過執行個體了。靜態變數或靜態方法都可以在不產生具體執行個體的情況下直接調用,這樣的變數或方法不會因為類的執行個體化而有所改變。
實現 Singleton 模式的辦法通常有三種:
1.用靜態方法實現 Singleton;
2.以靜態變數為標誌實現 Singleton;
3.用註冊器機制來建立 Singleton。
對於上面3種方法,我覺得第一種很好用,寫的串連池用了第一種和第三種方法。用第一種方法使得怎麼取都是那一個串連池,用第三種方法使得只存在那一個串連池。
第一種方法具體實現為:
聲明建構函式為 private,防止通過除由我們提供的方法之外的任意方式來建立一個執行個體,如果不把建構函式聲明為private,編譯器就會自作聰明的自動同步一個預設的friendly構造器。下面是摘抄的一個例子:
public class Singleton
{
private static Singleton s;
private Singleton()
{
};
public static Singleton getInstance()
{
if (s == null)
s = new Singleton();
return s;
}
}
// 測試類別
class singletonTest
{
public static void main(String[] args)
{
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1==s2)
System.out.println
("s1 is the same instance with s2");
else
System.out.println
("s1 is not the same instance with s2");
}
}
singletonTest運行結果是:
s1 is the same instance with s2
這證明我們只建立了一個執行個體,再怎麼取都是那個執行個體,很簡單也很實用。
對於第二種實現方法,在類中加入一個靜態變數做為標誌,每次都在建構函式裡進行檢察。
下面是我寫的一個例子:
public class Singleton {
static boolean existInstance=false;
public Singleton()
{
if (existInstance)
{
System.out.println("Already exist instanse!");
}
else
{
//...........................
System.out.println("Create an instanse!");
existInstance=true;
}
}
}
測試類別如下:
public class Test {
public static void main(String[] args) {
Singleton s1=new Singleton();
Singleton s2=new Singleton();
}
}
結果為:
Create an instanse!
Already exist instanse!
第二次的時候檢測到已經有執行個體,接下來要怎麼做就看自己的了。
與第一種方法相比,第一種是隨便你怎麼弄,都是那個執行個體,第二種是只能在第一次產生一個執行個體,再往後就會報錯了。
下面來看看第三種方法:用註冊器機制來建立 Singleton。
這種方法首先要建立一個管理器,用集合中的Hashtable 和Enumeration來實現addItem(Object key, Object value),getItem(Object key),removeItem(Object key)等方法實現,將key和value一一關聯起來,建立執行個體前首先用addItem方法進行註冊,再用getItem方法擷取執行個體。
Hashtable中的key是唯一的,從而保證建立的執行個體是唯一的,用註冊器機制來建立 Singleton模式的好處是易於管理,可以同時控制多個不同類型的Singleton 執行個體。
現在,我把那個串連池的部分代碼弄出來講講第三種方法:
首先,定義個靜態hashtable:
public static Hashtable pools=new Hashtable();
當建立串連池成功的時候,把產生的串連池對象放入pools中:
DBConnectionPool pool=new DBConnectionPool(poolName, url, usr, pwd, max);(DBConnectionPool 是自訂的串連池對象)
pools.put(poolName, pool);
取串連的時候,用的是:
public Connection getConnection(String poolName)
{
DBConnectionPool pool=(DBConnectionPool)pools.get(poolName);
if(pool!=null)
{
return pool.getConnection();
}
return null;
}
前面說了,hashtable中的key值是唯一的,這樣,名字為poolName的串連池只能有一個。
講完了,收攤了,還看不懂我也沒話說了.......