前言
Singleton Design Pattern 是一種設計的模式,目的是確保執行環境(JVM)內只會有一個物件實例,有點類似於Bean在Spring容器管理的Singleton作用域,意思一個IOC容器中只會有唯一的物件。它們都是希望可以避免系統資源的浪費,且確定這一個物件是無狀態的(Stateless),並能讓類別的腳色定義能更明確。常見Scope為Singleton的例子就是Spring boot專案裡的Service或是自己定義的Utility類別,我們並不需要每次都注入一個新的物件吧!
獨體設計模式建構
Singleton Design Pattern有幾個關鍵步驟來實踐
- 類別的建構子存取修飾子固定設為private
- 目的為不予許其他外部類別使用new關鍵字來建立物件,也就保證了只有單一的物件
- 使用private static final來實體化這一物件
- 因為物件只需要一份就好,所以在類別內使用private static final來宣告實體化這一物件,並表示該物件不可由外部類別直接存取(private),同時在JVM只會有一份(static),且該物件參考永遠不能指向其他參考(final)
- 提供公開的Getter方法來存取此物件
- 最後需要一個公開的Getter方法來存取物件,慣例上會使用getInstance來返回此物件
1 | class SingletonPattern { |
補充
在使用static必須要十分小心,加上static的變數會讓類別變成一個有狀態(State)的類別,如果在多執行續的情況下,常會造成結果跟預期的不相同,如下就是一個錯誤的例子,之前某舊專案使用到分頁,當時使用static來存放第幾筆資料和抓取數量,想說可以在Controller設定好資料,再EBO那邊直接再取就好,但經前輩指導後,這在多執行緒時就會有嚴重問題,這就是為何static要盡可能使用再無狀態的類別裡面!
1 | class Pager { |
前言提到的Bean作用域有分為下列幾種,最常使用的就是Singleton和Prototype,兩者差別就是前者適用無狀態(Stateless),後者適用有狀態的(Stateful)Bean
- Singleton
- 為預設的bean scope,整個IoC容器只會有唯一的實例
- Prototype
- 每次被調用都是建構新的實例
- Request
- 實例的scope為HTTP Request,同個request的實例才會相同 (Web環境才存在的scope)
- Session
- 實例的scope為HTTP Session,同個session的實例才會相同 (Web環境才存在的scope)