站長留言

  • ✅ 本站維護及更新歷史紀錄,詳情請參考公告
  • ✅ 有任何意見、想法,歡迎留言給Spicy知道喔
  • ✅ 固定於每周一至周五更新Blogger文章,周末不定期
程式Design PatternJava

【Design Pattern】5:Singleton Pattern 單例模式、獨體模式 (創造)

上一篇:Factory Method Pattern 工廠方法模式 (創造)

Introduction 簡介

  1. 一個class,只有一個實體
  2. 一個global point
  3. lazy instantiaze


Comparison 比較

寫法1:未考慮多執行緒

// 多執行緒會出錯 public class Singleton1 { private static Singleton1 uniqueInstance; private Singleton1() {} public static Singleton1 getInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton1(); } return uniqueInstance; } }

寫法2:多執行緒

  • 將 getInstance() 同步化 synchronized
  • 同步化影響效能
  • 實際上只有第一次執行 getInstance() 才需要同步化
// synchronized,但位置錯誤會嚴重影響效能 public class Singleton2 { private static Singleton2 uniqueInstance; private Singleton2() {} public static synchronized Singleton2 getInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton2(); } return uniqueInstance; } }

寫法3:先 new 實體

// 先 new 實體,有點影響初始化效能 public class Singleton3 { private static Singleton3 uniqueInstance = new Singleton3(); // 宣告成private,只有Singleton能呼叫建構子 private Singleton3() {} public static Singleton3 getInstance() { return uniqueInstance; } }

寫法4:Double-Checked Locking

  • synchronized 換位置
  • volatile + synchronized
// Double-Checked Locking // 效能佳 public class Singleton4 { private volatile static Singleton4 uniqueInstance; private Singleton4() {} public static synchronized Singleton4 getInstance() { if (uniqueInstance == null) { synchronized (Singleton4.class) { uniqueInstance = new Singleton4(); } } return uniqueInstance; } }

寫法5:initialization-on-demand holder

  • 把instance的初始化投入到一個inner class的初始過程中
// initialization-on-demand holder // 內部類別不會影響初始化效能 public class Singleton5 { private Singleton5() {} private static class LazyHolder{ static final Singleton5 INSTANCE = new Singleton5(); } public static Singleton5 getInstance() { return LazyHolder.INSTANCE; } }

使用時機

  • 需要控制實體個數
  • 通常適合使用Singleton Pattern的機會不多
  • The abstract factory 抽象工廠, builder, and prototype patterns can use singletons in their implementation.
  • Facade objects 表象物件 are often singletons because only one facade object is required.

全域變數 vs Singleton

  • 率先實體化 比 拖延實體化 更浪費資源
  • 全域變數無法保證只有一個實體
  • 濫用全域變數,會造成 namespace 汙染
  • Singleton其實也是一種全域變數

Disadvantage 缺點

  • 系統與Singleton產生隱含的耦合關係
  • 系統變得不易理解
  • 增加測試的難度

Extensive Reading 延伸閱讀

Reference 參考資料

  1. 圖片:https://codepumpkin.com/preventing-cloning-in-singleton-design-pattern/
  2. wiki:https://en.wikipedia.org/wiki/Singleton_pattern
  3. 搞笑談軟工:http://teddy-chen-tw.blogspot.com/2013/08/singleton-pattern.html
  4. wiki:https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom
下一篇:Command Pattern 命令模式 (行為)

沒有留言:

張貼留言

本網站建議使用電腦或平板瀏覽