前言
單例模式是最簡(jiǎn)單的一種模式。在Go中,單例模式指的是全局只有一個(gè)實(shí)例,并且它負(fù)責(zé)創(chuàng)建自己的對(duì)象。單例模式有減少內(nèi)存和系統(tǒng)資源開(kāi)銷、防止多個(gè)實(shí)例產(chǎn)生沖突等優(yōu)點(diǎn)。
因?yàn)閱卫J奖WC了實(shí)例的全局唯一性,并且只被初始化一次,所以比較適合全局共享一個(gè)實(shí)例,且只需要被初始化一次的場(chǎng)景,例如數(shù)據(jù)庫(kù)實(shí)例、全局配置、全局任務(wù)池等。
單例模式又分為餓漢方式和懶漢方式。餓漢方式是指全局的單例實(shí)例在包被加載時(shí)創(chuàng)建,而懶漢方式指全局的單例實(shí)例在第一次被使用時(shí)創(chuàng)建。其中懶漢方式是開(kāi)源項(xiàng)目中使用最多的方式。
示例代碼
Go
懶漢方式的缺點(diǎn)是非并發(fā)安全,實(shí)際使用中一般加鎖,或者使用sync.Once
package singleton
import "sync"
type Singleton interface {
foo()
}
type singleton struct{}
func (s singleton) foo() {}
var (
instance *singleton
once sync.Once
)
func GetInstance() Singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}
單元測(cè)試
package singleton
import (
"sync"
"testing")
const parCount = 100
func TestSingleton(t *testing.T) {
ins1 := GetInstance()
ins2 := GetInstance()
if ins1 != ins2 {
t.Fatal("instance is not equal")
}
}
func TestParallelSingleton(t *testing.T) {
start := make(chan struct{})
wg := sync.WaitGroup{}
wg.Add(parCount)
instance := [parCount]Singleton{}
for i := 0; i < parCount; i++ {
go func(index int) {
<-start
instance[index] = GetInstance()
wg.Done()
}(i)
}
close(start)
wg.Wait()
for i := 1; i < parCount; i++ {
if instance[i] != instance[i-1] {
t.Fatal("instance is not equal")
}
}
}
Python
python的包是天然的單例模式,只要放到單獨(dú)的包中,import時(shí)就是引用的單例。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-825827.html
如果要在一個(gè)包內(nèi)使用設(shè)計(jì)模式,也有以下幾種方式。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-825827.html
使用函數(shù)裝飾器實(shí)現(xiàn)單例
def singleton(cls):
_instance = {}
def inner():
if cls not in _instance:
_instance[cls] = cls()
return _instance[cls]
return inner
@singleton
class MyCls:
def __init__(self):
pass
if __name__ == "__main__":
a = MyCls()
b = MyCls()
print(id(a) == id(b)) # 輸出結(jié)果應(yīng)為 True
使用類裝飾器實(shí)現(xiàn)單例
class Singleton:
def __init__(self, cls):
self._cls = cls
self._instance = {}
def __call__(self):
if self._cls not in self._instance:
self._instance[self._cls] = self._cls()
return self._instance[self._cls]
@Singleton
class MyCls:
def __init__(self):
pass
if __name__ == "__main__":
a = MyCls()
b = MyCls()
print(id(a) == id(b)) # 輸出結(jié)果應(yīng)該是True
參考
- 知乎 - Crossin - Python單例模式的N種實(shí)現(xiàn)
到了這里,關(guān)于[設(shè)計(jì)模式]創(chuàng)建型模式-單例模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!