Singleton 設計模式

說明

同個請求的生命週期裡,對於使用 singleton 的類別永遠只會產生一個實體 (instance)


做法

把建構子設為 private,建立一個 static 的 getInstance function ,在裡面控制只能 new 一次實體。


常用情境

  • 登入
  • 快取
  • 資料庫連線
  • 與驅動程式的溝通

PHP 實作範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Singleton
{
/** Singleton instance */
private static $instance = null;

/** Constructor not to be used */
private function __construct()
{

}

/**
* Gets the instance of Singleton.
*
* @return self
*/
public static function getInstance()
{
if (!isset(self::$instance)) {
self::$instance = new self();
}

return self::$instance;
}
}

多執行緒語言需注意的情況

要注意多執行緒環境中,可能因時間差造成產生兩的個 instance
解法(以 Java 為例):

  • 使用同步化 (synchronized),缺點為其實只有第一次初始化的時候才需要使用 synchronzied ,因爲 instance 已經產生,後面都是多餘的,這會導致效能的浪費。

  • 預先初始化(eager initialization), 一開始就初始化,不管後面會不會用到,缺點是若沒有用到就是浪費記憶體。

  • 使用雙重檢查上鎖,先檢查是否已經建立了 instance,如果沒有才進行同步化,也就是只有第一次呼叫才會使用同步化。

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

Reference

深入淺出設計模式 (Head First Design Patterns)