設計模式 - 單例模式 (Creational Patterns - Singleton Pattern)
前言
單例模式處處可見,而我個人目前使用單例模式的時機是,當今天確定此物件只需有一個時就使用single pattern。但是在某天有幸看到一篇文章評論Singleton濫用情形,開始思考單一Class的必要性。
單例模式特性
- 確保整個Application只會有此一個物件
- 為了確保整個Application只會有此物件,所以會需要static關鍵字,這也代表著會變成全域物件
單例模式會讓物件變成全域物件,這也是許多神人對與單例模式濫用批評的原因,會開放其實沒有必要變成全域的物件被接觸到
使用時機
當此物件是全域的,而且容易連續被使用以及需要強調單一則可以考慮使用。
- Logger
- Configuration
- Cache
範例
Singleton分為兩種實踐方式,Lazy/Early懶漢與餓漢,實作Singleton最重要的是,多執行續時Singleton會不會有重複創建的問題,所以在Lazy實做時就會使用到最基本的Java Lock (synchronized),而Early使用到Final前綴字。
懶漢與餓漢差別
在於物件的初始化實機,懶就是晚一點餓就是一開始就來。
LazySingleton.java
public class LazySingleton {
private static volatile LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance(String value) {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
}
LazySingleton.java
public class EarlySingleton {
private EarlySingleton() {}
private static class EarlySingletonHolder {
private static final EarlySingleton INSTANCE = new EarlySingleton();
}
public static EarlySingleton getInstance() {
return EarlySingletonHolder.INSTANCE;
}
}
結論
如果想創建一個,常常被全域使用,而且重複創造物件是種很浪費的行為時可以考慮使用Singleton,若是在Java初始化時對於物件佔用空間影響覺得還好時,可以考慮使用餓漢;相反的則使用懶漢,當物件被第一次呼叫時在創建。
留言
張貼留言