設計模式之第0章-單例模式(Java實現)


設計模式之第0章-單例模式(Java實現)

  當當當當~首先有請最簡單的單例模式登場,先來個自我介紹吧

單例模式之自我介紹

  我,單例模式(Singleton Pattern)是一個比較簡單的模式,我的定義如下:

  Ensure a class has only one instance,and provide a global point of access to it.(確保其某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。)單例模式的通用類圖如下:

  

  Singleton類稱為單例類,通過使用private的構造函數確保了在一個應用中只產生一個實例,並且是自行實例化的。

單例模式之自我分析

  做人,哦不,做模式不能自滿,所以先談談我的缺點,我的缺點如下:

  • 我一般沒有接口,擴展很困難,如果想擴展的話,除了修改代碼基本上沒有第二種方式。當然了,特殊情況下,我也可以實現接口、被繼承等,這個需要你們自行判斷。
  • 測試不便。在並行開發中,如果你們沒有把我完成,那么是沒有辦法進行測試的。
  • 還有一點,我與單一職責原則也有沖突,一個類本應實現一個邏輯,不該關心是否是單例的,是不是要單例取決於環境,但是我把單例和業務邏輯融合在一個類中了。

  終於該說優點了~挺好了,比缺點可是要多的說:

  • 對唯一實例的受控訪問。由於我的類封裝了我唯一的實例,所以可以嚴格控制用戶以及何時訪問它。
  • 縮小名空間。我可以避免那些存儲唯一實例的全局變量污染名空間。
  • 允許對操作和表示的精化。
  • 允許可變數目的實例。
  • 比類操作更靈活。

單例模式之實現

  俗話說,說的比唱的好聽。為了證明我唱的也很好聽,接下來我就以人類的一夫一妻制來具體講解一下如何實現我的模式~一夫一妻制又稱作”單偶婚“,“個體婚”,據說一夫一妻制起源於秦始皇統一天下之后,自大秦一統天下,中國酒實行了一夫一妻制,尤其是在漢朝“罷黜百家,獨尊儒術”開始,古人嚴格執行了這一制度blablabla...(此處省略n字)。咳咳,跑題了,我們接着談一夫一妻制,哦不,單例模式,首先得有個妻子類:

 1 public class Wife{
 2 
 3     private static final Wife wife = new Wife();
 4     private Wife(){
 5 
 6     }
 7     public static Wife getInstance(){
 8         return wife;
 9     }
10     public static void say(){
11         System.out.println("I am Y's wife!");
12     }
13 }

   通過定義一個私有訪問權限的構造函數,可以避免被其他類new出來一個對象,而Wife自己可以new一個對象出來,其他的類對該類的訪問可以通過getInstance獲得一個對象。妻子有了,老公Y自然要出場了,其類代碼如下:

1 public class Y{
2     public static void main(String[] args) {
3         for (int day=0; day<3;day++ ) {
4             Wife wife = Wife.getInstance();
5             wife.say();
6         }
7     }
8 }

  運行結果如下:

  I am Y's wife!

  I am Y's wife!

  I am Y's wife!

  Y每天回家見到的妻子,都是同一個妻子,不會出現開門后,一看,呦呵,老婆怎么變了?如有此情況,請速與我聯系!

單例模式之優化OR問題

  有人嫌這樣麻煩,因為無論是都使用這個類,都會創建一個instance對象,如果創建這個很耗時,比如需要連接10**9(python的10的9次方寫法)次數據庫,並且還不一定使用,那該這么辦?於是乎有“聰明人”想到如下的方法: 

public class Singleton {
    private static Singleton instance;
    private Singleton (){}

    public static Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
    }
}

  是不是感覺很不錯,很好?這個是傳說中的懶漢模式其實這個有個很大的問題,如果是高並發情況下,可能A線程在創建實例,但是還沒獲取對象,B此時也在執行,判斷也為真,所以又獲得一個對象,如此下去,你的妻子會越來越多!沒辦法了么?不,當然有,且往下看:

 1 public class Singleton {
 2     private static Singleton instance;
 3     private Singleton (){}
 4     public static synchronized Singleton getInstance() {
 5     if (instance == null) {
 6         instance = new Singleton();
 7     }
 8     return instance;
 9     }
10 }

  這種寫法確實解決了問題,但是效率么,嘖嘖,99%情況下不需要同步我會告訴你么?

奇技淫巧:單例模式之反射實現

 1 public class Singleton{
 2     private static Singleton singleton;
 3     static{
 4         try{
 5             class cl = class.forName(Singleton.class.getName());
 6             //獲得無參構造
 7             Constructor con = cl.getDeclaredConstructor();
 8             //設置無參構造是可訪問的
 9             con.setAccessible(true);
10             //產生一個實例對象
11             singleton = (Singleton)con.newInstance();
12         }
13         catch(Exception e)
14         {
15             
16         }
17     }
18 
19     public static Singleton getSingleton(){
20         return singleton;
21     }
22 }

  通過獲得類構造,然后設置訪問權限,生成一個對象,然后提供外部訪問,保證內存對象單一。

  以上就是我,單例模式,謝謝大家~下回就是我的大哥來做演講了,欲知后事如何,且聽下回分解。

  第一篇:設計模式之序章-UML類圖那點事兒

 

  PS:本博客歡迎轉發,但請注明博客地址及作者~

   博客地址:http://www.cnblogs.com/voidy/

   博客新址:http://voidy.net

   <。)#)))≦

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM