有些內容使用中英雙語,有些只有英文或中文。歡迎使用與分享任何內容,但先來信告知並標示此部落格為出處。
Some parts use both Chinese and English, but some parts use only one language. Feel free to share, but please contact me first and list this blog as your reference.

2014年5月18日 星期日

Design Patterns 筆記 - Singleton Pattern 單例模式

初學Design Pattern,如有謬誤或超級大錯還請指教。

如不知道什麼是 Design Patterns,可先閱覽一下這篇:Design Patterns 筆記 - Overview

想知道其他種 Design Patterns,請看這篇:Design Patterns 筆記 - Categories 分類條列

另外,如果不懂Java的介面,可以參考這一篇:JAVA - 什麼是介面?


以下內容主要從 tutorialspoint 的 Design Patterns - Singleton  Pattern 翻譯而來。
故事背景跟額外補充是參考自王者歸來:品味Java的21種設計模式

故事背景:

很多專案或是系統,都有一些開發人員定義的設定檔或資料檔,該如何讀取這些檔案內容?
好像不難啊? 直接寫一個 class ,能讀取檔案,能回傳設定檔的內容即可。
用戶在使用時直接建立此物件即可使用。

這會有問題嗎? 有!
如果系統之中有多處需要用到同一個設定檔呢? 那是不是會new()非常多個設定檔物件!
嚴重浪費系統空間資源,如果設定檔內容較大,那不是死定了嗎 = =?

所以其實我們只需要一個設定檔物件即可,Singleton Pattern 就是解決方案!


概念 :

單例模式是Java理最簡單的 dessign pattern 之一。
此 pattern 被分類在建立型模式 (Creational Patterns),建立物件時最好的方式之一。

此 pattern 是一個負責創造唯一物件(object)的類別(class)。
此類別也能夠讓用戶直接溝通此物件 (使用 static 就不用宣告實例)。


實作範例 :

我們創造出一個 SingleObject 類別,他有一個私有建構子(private constructor),並且有一個自己的 static 實例。

SingleObject 類別有一個 static 的函式,可以讓外面溝通,拿到此 (SingleObject) 實例。
Main 主程式(SingletonPatternDemo) 使用SingleObject 來拿到 SingleObject 實體物件。

Singleton Pattern UML Diagram

Step 1

創造一個 Singleton 類別,在一開始直接 new 一個 static 的物件(唯一一個)。
之後有需要即可用 getInstance() 溝通呼叫。

SingleObject.java
public class SingleObject {

   //create an object of SingleObject
   private static SingleObject instance = new SingleObject();

   //make the constructor private so that this class cannot be
   //instantiated
   private SingleObject(){}

   //Get the only object available
   public static SingleObject getInstance(){
      return instance;
   }

   public void showMessage(){
      System.out.println("Hello World!");
   }
}

Step 2

從 singleton 類別取得唯一的物件。

SingletonPatternDemo.java
public class SingletonPatternDemo {
   public static void main(String[] args) {

      //illegal construct
      //Compile Time Error: The constructor SingleObject() is not visible
      //SingleObject object = new SingleObject();

      //Get the only object available
      SingleObject object = SingleObject.getInstance();

      //show the message
      object.showMessage();
   }
}

Step 3

確認執行結果
Hello World!


額外補充:eager(飢餓式) V.S. lazy(懶惰式)

在 Java 的 Singleton Pattern 之中,有兩種實作方式,一種是飢餓式(eager),一種是懶惰式(lazy)。

書上翻譯成飢餓,但 eager 應為"渴望、熱切的",在建立物件實例比較積極,
所以再載入類別時就建立實例。上述的實例就是屬於 eager。
重點是這行: private static SingleObject instance = new SingleObject();

而懶惰式,就是懶,你知道的...懶人都是最後關頭才要做事XD
所以等到真正要使用時才會建立物件實例,如果一直不需要此物件,就不會創造物件實例。
有延遲載入的概念,可以節省資源,不用一開始就把所有的資料載入。
請看此範例~ 一開始設為 null ,並把 getInstance() 稍作修改


延伸閱讀:

1. Design Patterns 筆記 - Overview
2. Design Patterns 筆記 - Categories 分類條列 (其他Design Pattern 介紹)


Reference:

1. tutorialspoint
2. 王者歸來:品味Java的21種設計模式


If you want to use (copy, paste or quote) my original article, please contact me through email (autek.roy@gmail.com). If there is any mistake or comment, please let me know. :D

如要使用(複製貼上或轉載)作者原創文章,請來信跟我聯絡 (autek.roy@gmail.com)。如果有發現任何的錯誤與建議請留言或跟我連絡。 : )

沒有留言:

張貼留言

請留下您的任何想法或建議!
Please leave any thought or comment!