所謂“懶漢式”與“餓漢式”的區別,是在與建立單例對象的時間的不同。
“懶漢式”是在你真正用到的時候纔去建這個單例對象:
比如:有個單例對象
public class Singleton{
private Singleton(){}
private static Singleton singleton = null; //不建立對象
public static synchronized Singleton getInstance(){
if(singleton == null) { //先判斷是否爲空
singleton = new Singleton (); //懶漢式做法
}
return singleton ;
}
}
“餓漢式”是在不管你用的用不上,一開始就建立這個單例對象:比如:有個單例對象
public class Singleton{
public Singleton(){}
private static Singleton singleton = new Singleton(); //建立對象
public static Singleton getInstance(){
return singleton ;//直接返回單例對象 }}
它有以下幾個要素:
· 私有的構造方法
· 指向自己實例的私有靜態引用
· 以自己實例爲返回值的靜態的公有的方法
廢話少說,先列出代碼(java)
[java] view plain copy
1. class Instance{}
2. //懶漢式
3. class LSingle{
4. private static Instance _instance = null;
5. private LSingle(){}
6.
7. public static Instance getInstance(){
8. if(_instance==null){
9. synchronized(LSingle.class){
10. _instance = new Instance();
11. }
12. }
13. return _instance;
14. }
15. }
16. //餓漢式
17. class ESingle{
18. private static Instance _instance = new Instance();
19.
20. private ESingle(){}
21.
22. public static Instance getInstance(){
23. return _instance;
24. }
25. }
單件模式用途:
單件模式屬於工廠模式的特例,只是它不需要輸入參數並且始終返回同一對象的引用。
單件模式能夠保證某一類型對象在系統中的唯一性,即某類在系統中只有一個實例。它的用途十分廣泛,打個比方,我們開發了一個簡單的留言板,用戶的每一次留言都要將留言信息寫入到數據庫中,最直觀的方法是沒次寫入都建立一個數據庫的鏈接。這是個簡單的方法,在不考慮併發的時候這也是個不錯的選擇。但實際上,一個網站是併發的,並且有可能是存在大量併發操作的。如果我們對每次寫入都創建一個數據庫連接,那麼很容易的系統會出現瓶頸,系統的精力將會很多的放在維護鏈接上而非直接查詢操作上。這顯然是不可取的。
如果我們能夠保證系統中自始至終只有唯一一個數據庫連接對象,顯然我們會節省很多內存開銷和cpu利用率。這就是單件模式的用途。當然單件模式不僅僅只用於這樣的情況。在《設計模式:可複用面向對象軟件的基礎》一書中對單件模式的適用性有如下描述:
1、當類只能有一個實例而且客戶可以從一個衆所周知的訪問點訪問它時。
2、當這個唯一實例應該是通過子類化可擴展的,並且客戶應該無需更改代碼就能使用一個擴展的實例時。
關於Instance類應該如何設計:
如上面敘述,我們保證單件模式類是我們取得單件實例的唯一訪問點。那麼我們應該保證在程序中儘量避免允許創建Instance實例。
通過將構造函數聲明爲private可以防止程序員通過new關鍵字調用構造上函數創建對象。並且在Instance類中創建getXXX()方法調用構造函數並返回具體Instance實例。具體代碼如下:
[java] view plain copy
1. class Instance{
2. private Instance(){}
3.
4. public static Instance getSelf(){
5. return new Instance();
6. }
7. }
8. //懶漢式
9. class LSingle{
10. private static Instance _instance = null;
11. private LSingle(){}
12.
13. public static Instance getInstance(){
14. if(_instance==null){
15. synchronized(LSingle.class){
16. _instance = Instance.getSelf();
17. }
18. }
19. return _instance;
20. }
21. }
22. //餓漢式
23. class ESingle{
24. private static Instance _instance = Instance.getSelf();
25.
26. private ESingle(){}
27.
28. public static Instance getInstance(){
29. return _instance;
30. }
31. }
下面對單件模式的懶漢式與餓漢式進行簡單介紹:
1、餓漢式:在程序啓動或單件模式類被加載的時候,單件模式實例就已經被創建。
2、懶漢式:當程序第一次訪問單件模式實例時才進行創建。
如何選擇:如果單件模式實例在系統中經常會被用到,餓漢式是一個不錯的選擇。
反之如果單件模式在系統中會很少用到或者幾乎不會用到,那麼懶漢式是一個不錯的選擇。