一、什么是單例模式
單例模式是一種常用的軟件設計模式,其定義是單例對象的類只能允許一個實例存在。
許多時候整個系統只需要擁有一個的全局對象,這樣有利于我們協調系統整體的行為。比如在某個服務器程序中,該服務器的配置信息存放在一個文件中,這些配置數據由一個單例對象統一讀取,然后服務進程中的其他對象再通過這個單例對象獲取這些配置信息。這種方式簡化了在復雜環境下的配置管理。
單例的實現主要是通過以下兩個步驟:
- 將該類的構造方法定義為私有方法,這樣其他處的代碼就無法通過調用該類的構造方法來實例化該類的對象,只有通過該類提供的靜態方法來得到該類的唯一實例;
- 在該類內提供一個靜態方法,當我們調用這個方法時,如果類持有的引用不為空就返回這個引用,如果類保持的引用為空就創建該類的實例并將實例的引用賦予該類保持的引用。
二、單例模式的結構
角色 | 含義 |
---|---|
單例類 | 包含一個實例且能自行創建這個實例的類 |
訪問類 | 使用單例的類 |
三、單例模式的代碼實現
python實現
class Singleton(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
class Test(Singleton):
pass
t1 = Test()
t2 = Test()
print(t1 is t2) # True
golang實現
package singleton
type singleton struct{}
var instance = &singleton{}
var once sync.Once
func GetSingleton() *singleton {
once.Do(func() {
singleton = &singleton{}
})
return singleton
}
四、單例模式的優缺點
優點
- 在內存中只有一個對象,節省內存空間;
- 避免頻繁的創建銷毀對象,可以提高性能;
- 避免對共享資源的多重占用,簡化訪問;
- 為整個系統提供一個全局訪問點。
缺點
- 不適用于變化頻繁的對象;
- 濫用單例將帶來一些負面問題,如為了節省資源將數據庫連接池對象設計為的單例類,可能會導致共享連接池對象的程序過多而出現連接池溢出;
- 如果實例化的對象長時間不被利用,系統會認為該對象是垃圾而被回收,這可能會導致對象狀態的丟失;
五、單例模式的應用場景
- 需要生成唯一序列的環境
- 需要頻繁實例化然后銷毀的對象。
- 創建對象時耗時過多或者耗資源過多,但又經常用到的對象。
- 方便資源相互通信的環境
* 在我們的windows桌面上,我們打開了一個回收站,當我們試圖再次打開一個新的回收站時,Windows系統并不會為你彈出一個新的回收站窗口。,也就是說在整個系統運行的過程中,系統只維護一個回收站的實例。這就是一個典型的單例模式運用。
* 網站的計數器,一般也是采用單例模式實現,如果你存在多個計數器,每一個用戶的訪問都刷新計數器的值,這樣的話你的實計數的值是難以同步的。
* 線程的線程池的設計一般也是采用單例模式,這是由于線程池需要方便對池中的線程進行控制
* 對于一些應用程序的日志應用,或者web開發中讀取配置文件都適合使用單例模式,如HttpApplication 就是單例的典型應用。