參考:https://github.com/mohuishou/go-design-pattern/tree/master/01_singleton
什么是單例模式?
保證某個(gè)類在一個(gè)運(yùn)行環(huán)境中只有一個(gè)實(shí)例, 并提供一個(gè)訪問實(shí)例的全局節(jié)點(diǎn);例如:mysql游標(biāo)等掌栅,一個(gè)環(huán)境中必須保證只有一個(gè)锭硼。比如我們的APP中有一個(gè)類用來保存運(yùn)行時(shí)全局的一些狀態(tài)信息丹莲,如果這個(gè)類實(shí)現(xiàn)不是單例的,那么App里面的組件能夠隨意的生成多個(gè)類用來保存自己的狀態(tài),等于大家各玩各的,那這個(gè)全局的狀態(tài)信息就成了笑話了虱黄。而如果把這個(gè)類實(shí)現(xiàn)成單例的,那么不管App的哪個(gè)組件獲取到的都是同一個(gè)對(duì)象(比如Application類寸爆,除了多進(jìn)程的情況下)礁鲁。
Ensure a class has only one instance, and provide a global pointof access to it.
為什么要用到單例模式?
在軟件設(shè)計(jì)中, 經(jīng)常有一些特殊的類赁豆,需要保證在系統(tǒng)中只有唯一一個(gè)實(shí)例才能保證正確性和效率仅醇。
如何才算一個(gè)單例模式?
不管那種模式最終目的只有一個(gè)魔种,就是只實(shí)例化一次析二,只允許一個(gè)實(shí)例存在。
懶漢式實(shí)現(xiàn)
這里我們使用三種方式實(shí)現(xiàn)餓漢模式节预。先說一下什么是懶漢模式吧叶摄,從懶漢這兩個(gè)字,我們就能知道安拟,這個(gè)人很懶蛤吓,所以他不可能在未使用實(shí)例時(shí)就創(chuàng)建了對(duì)象,他肯定會(huì)在使用時(shí)才會(huì)創(chuàng)建實(shí)例糠赦,這個(gè)好處的就在于会傲,只有在使用的時(shí)候才會(huì)創(chuàng)建該實(shí)例。下面我們一起來看看他的實(shí)現(xiàn):
package singleton
import "sync"
var (
singleton *Singleton
once = &sync.Once{}
)
func GetInstance() *Singleton {
if singleton == nil {
once.Do(func() {
singleton = &Singleton{}
})
}
return singleton
}
餓漢式實(shí)現(xiàn)方式
什么是餓漢拙泽?
餓漢模式我們很好解釋了淌山,因?yàn)樗I呀,所以很著急的就創(chuàng)建了實(shí)例顾瞻,不用等到使用時(shí)才創(chuàng)建泼疑,這樣我們每次調(diào)用獲取接口將不會(huì)重新創(chuàng)建新的對(duì)象,而是直接返回之前創(chuàng)建的對(duì)象荷荤。比較適用于:如果某個(gè)單例使用的次數(shù)少退渗,并且創(chuàng)建單例消息的資源比較多,那么就需要實(shí)現(xiàn)單例的按需創(chuàng)建梅猿,這個(gè)時(shí)候懶漢模式就是一個(gè)不錯(cuò)的選擇氓辣。不過也有缺點(diǎn),餓漢模式將在包加載的時(shí)候就會(huì)創(chuàng)建單例對(duì)象袱蚓,當(dāng)程序中用不到該對(duì)象時(shí)钞啸,浪費(fèi)了一部分空間,但是相對(duì)于懶漢模式,不需要進(jìn)行了加鎖操作体斩,會(huì)更安全梭稚,但是會(huì)減慢啟動(dòng)速度。
package singleton
// Singleton 餓漢式單例
type Singleton struct{}
var singleton *Singleton
func init() {
singleton = &Singleton{}
}
// GetInstance 獲取實(shí)例
func GetInstance() *Singleton {
return singleton
}