目录
- 单例模式
- 一、简介
- 二、代码实现
- 1、懒汉模式
- 2、饿汉模式
- 3、改进型懒汉模式
- 4、 sync.once实现
- 5、测试用例
单例模式
一、简介
单例模式(Singleton Pattern)是软件设计中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
二、代码实现
1、懒汉模式
非线程安全。当正在创建时,有线程来访问此时LazyInstance = nil就会再创建,单例类就会有多个实例了。
var LazyInstance *Instance
func GetLazyInstance() *Instance {
if LazyInstance == nil {
LazyInstance = &Instance{
Counter: 0,
Name: "LazyInstance",
}
}
return LazyInstance
}
2、饿汉模式
初始化比较耗时间的话,获取的性能比较慢
var HungryInstance = &Instance{Name: "HungryInstance", Counter: 0}
func GetHungryInstance() *Instance {
return HungryInstance
}
3、改进型懒汉模式
每次读取都加锁了,比较好性能,更多的时候获取是不用加锁的
var mu sync.Mutex
var LazyInstancePlus *Instance
func GetLazyInstancePlus() *Instance {
mu.Lock()
defer mu.Unlock()
if LazyInstancePlus == nil {
LazyInstancePlus = &Instance{
Counter: 0,
Name: "LazyInstancePlus",
}
}
return LazyInstancePlus
}
只为空的时候加锁,提高了性能
var LazyInsPlusPlus *Instance
func GetLazyInsPlusPlus() *Instance {
if LazyInsPlusPlus == nil {
mu.Lock()
defer mu.Unlock()
LazyInsPlusPlus = &Instance{
Counter: 0,
Name: "LazyInsPlusPlus",
}
}
return LazyInsPlusPlus
}
4、 sync.once实现
var once sync.Once
var SyncOnceInstance *Instance
func GetInstanceSyncOnce() *Instance {
once.Do(func() {
SyncOnceInstance = &Instance{
Counter: 0,
Name: "SyncOnceInstance",
}
})
return SyncOnceInstance
}
5、测试用例
package main
import (
"fmt"
"sync"
)
type Instance struct {
Name string
Counter int //详细参数
}
func (i *Instance) Hello() {
fmt.Printf("%s: my current counter is:%d\n", i.Name, i.Counter)
}
//省略实现
func main() {
//懒汉模式测试
ls := GetLazyInstance()
ls.Hello()
ls.Counter += 1
ls1 := GetLazyInstance()
ls1.Hello()
//饿汉模式测试
hs := GetHungryInstance()
hs.Hello()
hs.Counter += 10
hs1 := GetHungryInstance()
hs1.Hello()
//改进型懒汉模式
lsp := GetLazyInstancePlus()
lsp.Hello()
lsp.Counter += 100
lsp1 := GetLazyInstancePlus()
lsp1.Hello()
lspp := GetLazyInsPlusPlus()
lspp.Hello()
lspp.Counter += 1000
lspp1 := GetLazyInsPlusPlus()
lspp1.Hello()
//sync once 测试
sc := GetInstanceSyncOnce()
sc.Hello()
sc.Counter += 10000
sc1 := GetInstanceSyncOnce()
sc1.Hello()
}
结果:
LazyInstance: my current counter is:0
LazyInstance: my current counter is:1
HungryInstance: my current counter is:0
HungryInstance: my current counter is:10
LazyInstancePlus: my current counter is:0
LazyInstancePlus: my current counter is:100
LazyInsPlusPlus: my current counter is:0
LazyInsPlusPlus: my current counter is:1000
SyncOnceInstance: my current counter is:0
SyncOnceInstance: my current counter is:10000
完整代码和测试用例: https://gitee.com/ncuzhangben/GoStudy/tree/master/go-design-pattern/01-Singleton