Java設計模式之從[反恐精英控制檯]分析單例(Singleton)模式
所謂單例模式(Singleton),就是保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點的模式。
玩過反恐精英的同學應該都知道,遊戲當中是有個控制檯的,我們可以通過按`鍵(波浪線鍵)調出這個控制檯。控制檯的目的是為了方便開發人員除錯,當然我們也可以在裡面來修改一些遊戲引數,如輸入SV_GRAVITY 100可以把重力調整到100,那麼我們跳躍的高度就是原來的8倍了。
由於控制檯的遊戲的全域性通用的,因此我們希望這個控制檯類僅有一個例項。當我們訪問它的時候,如果它沒有例項化,則例項化之,如果它例項化了我們則返回它例項化的物件。這便是單例模式。
那麼,以Java為例,我們應該在何時將類的物件例項化呢?是在第一次載入類的時候?第一次需要返回例項的時候?因為物件的例項化時間順序的差異,我們可以寫出幾種單例模式的實現方法,本篇文字以懶漢、餓漢、巢狀類(內部靜態類)三種方法為例。程式碼如下:
class Log {
public void print(String str){
System.out.println(str + " - From 懶漢" );
}
private static Log logInstance;
private Log(){}
public static synchronized Log getInstance(){
if (logInstance == null){
logInstance = new Log();
}
return logInstance;
}
}
class Log2{
private static Log2 logInstance = new Log2();
private Log2(){}
public void print(String str){
System.out.println(str + " - From 餓漢" );
}
public static Log2 getInstance(){
return logInstance;
}
}
class Log3{
private static class LogHolder{
private static final Log3 logInstance = new Log3();
}
private Log3(){}
public static Log3 getInstance(){
return LogHolder.logInstance;
}
public void print(String str){
System.out.println(str + " - From 內部靜態類" );
}
}
class Singleton
{
public static void main(String[] args) {
Log log = Log.getInstance();
log.print("Hello world");
Log2 log2 = Log2.getInstance();
log2.print("Hello world");
Log3 log3 = Log3.getInstance();
log3.print("Hello world");
}
}
在上面的例子中,Log、Log2和Log3分別用懶漢、餓漢、內部靜態類實現了單例模式,它們能夠呼叫print方法,輸出我們傳入的字串。下面簡要來分析一下這3個類之間的差異。
Log類可以呼叫getInstance來返回一個Log例項,如果這個例項沒有被建立,則進行建立,否則直接返回例項,這個就是懶漢模式(需要的時候才進行判斷)。由於判斷是否存在和建立存在時間差,因此我加上了synchronized關鍵字保證它不會在多執行緒中遭到爭搶。這樣寫的代價是,系統會在同步鎖上有很大的開銷,假設很多地方需要使用到getInstance,那麼時間開銷會很大。
Log2類,將例項化寫在了一個static語句中,那麼,只要這個類被載入(這個類第一次被使用)時,就會建立logInstance物件。假設這個物件十分龐大,那麼我們在載入這個類的時候會花很多時間。另外,假設new Log2()執行失敗,我們將永遠無法得到Log2的例項。只要這個類被載入,則物件被建立,這個就是餓漢。
Log3類包含一個巢狀類(內部靜態類),它是Log2類的升級版。我們可以看到,logInstance的例項化被寫到了一個巢狀類中,那麼這個巢狀類被載入的時間也就是呼叫Log3.getInstance的時間,也就是說,只有我們呼叫了Log3.getInstance,這個物件才會被建立。
以上程式的執行結果為:
Hello world - From 懶漢
Hello world - From 餓漢
Hello world - From 內部靜態類
當一個類只期望有一個例項,且客戶可以從一個眾所周知的地方訪問它時,就可以考慮單例模式了。
相關文章
- java設計模式-單例模式SingletonJava設計模式單例
- 設計模式之單例模式(Singleton Pattern)設計模式單例
- 設計模式—singleton(單例模式)設計模式單例
- Singleton 單例設計模式單例設計模式
- 設計模式之“物件效能模式”: Singleton 單例模式(筆記)設計模式物件單例筆記
- PHP設計模式(四)單例模式(Singleton)PHP設計模式單例
- 《設計模式》 - 1. 單例模式( Singleton )設計模式單例
- 常用設計模式-單例模式(Singleton pattern)設計模式單例
- 設計模式--單例(Singleton Pattern)設計模式單例
- Scala 與設計模式(一):Singleton 單例模式設計模式單例
- PHP設計模式(一)—單例模式(Singleton Pattern)PHP設計模式單例
- Java設計模式之單例模式Java設計模式單例
- Java設計模式系列之單例設計模式Java設計模式單例
- 單例模式(Singleton)單例模式
- 單例模式 singleton單例模式
- 設計模式 - 單例模式Singleton的8種寫法設計模式單例
- 折騰Java設計模式之單例模式Java設計模式單例
- Java設計模式【單例模式】Java設計模式單例
- Java設計模式 | 單例模式Java設計模式單例
- Java設計模式——單例模式Java設計模式單例
- Java設計模式–單例模式Java設計模式單例
- Java設計模式-單例模式Java設計模式單例
- Java設計模式--單例模式Java設計模式單例
- 2.C#設計模式系列01_單例模式_SingletonC#設計模式單例
- 設計模式之單例模式設計模式單例
- 設計模式之☞單例模式設計模式單例
- 設計模式之---單例模式設計模式單例
- 設計模式之單例設計模式設計模式單例
- 單例模式(Singleton Pattern)單例模式
- 一天一個設計模式(二) - 單例模式(Singleton)設計模式單例
- Java常用設計模式-單例模式Java設計模式單例
- Javascript設計模式之單例模式JavaScript設計模式單例
- PHP 設計模式之——單例模式PHP設計模式單例
- golang設計模式之單例模式Golang設計模式單例
- js設計模式之單例模式JS設計模式單例
- Javascript 設計模式之單例模式JavaScript設計模式單例
- PHP 設計模式之單例模式PHP設計模式單例
- PHP設計模式之單例模式PHP設計模式單例
- Android設計模式之單例模式Android設計模式單例