前言 單例模式是最簡單的一種模式。在Go中,單例模式指的是全局只有一個實例,並且它負責創建自己的對象。單例模式有減少記憶體和系統資源開銷、防止多個實例產生衝突等優點。 因為單例模式保證了實例的全局唯一性,並且只被初始化一次,所以比較適合全局共用一個實例,且只需要被初始化一次的場景,例如資料庫實例、全局 ...
前言
單例模式是最簡單的一種模式。在Go中,單例模式指的是全局只有一個實例,並且它負責創建自己的對象。單例模式有減少記憶體和系統資源開銷、防止多個實例產生衝突等優點。
因為單例模式保證了實例的全局唯一性,並且只被初始化一次,所以比較適合全局共用一個實例,且只需要被初始化一次的場景,例如資料庫實例、全局配置、全局任務池等。
單例模式又分為餓漢方式和懶漢方式。餓漢方式是指全局的單例實例在包被載入時創建,而懶漢方式指全局的單例實例在第一次被使用時創建。其中懶漢方式是開源項目中使用最多的方式。
示例代碼
Go
懶漢方式的缺點是非併發安全,實際使用中一般加鎖,或者使用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
}
單元測試
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的包是天然的單例模式,只要放到單獨的包中,import時就是引用的單例。
如果要在一個包內使用設計模式,也有以下幾種方式。
使用函數裝飾器實現單例
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)) # 輸出結果應為 True
使用類裝飾器實現單例
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)) # 輸出結果應該是True
參考
本文來自博客園,作者:花酒鋤作田,轉載請註明原文鏈接:https://www.cnblogs.com/XY-Heruo/p/18020746