[設計模式] Singleton Pattern (單例模式) Part1

最近在學習Hibernate的時候,發現在原廠的Documentation裡面,使用了Singleton Pattern這樣的模式,就讓我藉由這篇文章複習一下Design Pattern吧。

設計模式在軟體開發中,指的是如何運用一個良好的思維邏輯來進行程式碼架構的規劃及撰寫。提到設計模式,一定會提到Gof等四位作者所撰寫的這本書吧:


今天想要介紹並且讓我自己複習的正是Singleton Pattern(單例模式)。Singleton Pattern在設計上是希望確保一個類別在系統運行的時候,只有一個實體(instance)產生,同時,這個類別必須要提供一個公開的方法讓其他人取得自己的實體。為什麼我們要使用者這個模式?

在某些情況下,你的程式只會希望有一個物件的實體存在,比如說,連接資料庫的物件、程式管理員的物件、處理印表機列印的類別等等。如果這些物件可以有多個實體,那每次需要這些功能的時候,我們都可以任意的new一個實體出來進行操作,這樣會造成相當恐怖的結果。

如果把Singleton Pattern實作出來,長相會是這樣


public class Singleton {

    private static Singleton instance;

    private Singleton () { }

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

這段程式碼的重點有三個:

  1. 要有一個私有(private)的靜態(static)方法:用來紀錄類別的實體。因為是私有的,所以外部沒辦法直接透過Singleton.instance來存取。
  2. 類別擁有一個私有的建構子:其他的方法沒辦法直接產生這個類別的實體,說的白話一點,就是不能夠用new Singleton()這樣的方式來產生實體,這是重點所在。
  3. 擁有一個公開取得物件實體的方法:由於是私有建構子(private constructor)的原因,要產生這個類別的實體,只能靠自己類別內的方法產生。但是又必須要讓外部能夠呼叫,所以要設定為公開的靜態方法
這種方式又稱為【Lazy Instantization】,中文可以翻作【延遲實體化】。為什麼呢?因為我們可以看到,我們只有需要這個物件的時候,利用Singleton.getInstance()這樣的方法來取得Singleton這個類別的實體,不需要的時候就不會產生,所以叫做延遲的實體化方法。

要怎麼驗證呢?很簡單,寫一個小程式測試一下就好了,兩個實體的hashcode應該是相同的囉:

Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());

Lazy Instantization的方法在Single Thread的程式中是可以正確運作的,但是當你的程式有兩個或兩個以上的threads在跑的時候,就會出現問題,這個部份我們留到part2再談囉!

Share this post!

Bookmark and Share

0 意見: