一、单例模式
1.1、简单介绍
保证一个类只能被全局实例化一次,即全局只能存在唯一一个实例供外部反复调用
1.2、饿汉式单例
在代码启动之初就初始化好全局唯一的单例
执行步骤与注意事项:
- 单例类与其构造函数定义为不可导出类型
- 代码启动之初就实例化对象(通过init()方法在引入包时实例化对象)
- 暴露GetInstance()方法用于获取实例
- 对单例类包装一层接口,使得在外部能够调用其方法
package singleton
var s *singleton
//init函数在引入包时自动调用
func init() {
s = newSingleton()
}
//单例对象
type singleton struct {
}
//构造函数
func newSingleton() *singleton {
return &singleton{}
}
//对象方法
func (s *singleton) Work() {
}
// 对外暴露的函数
// 此种方法在外部无法调用singleton中定义的函数,因为其被声明为内部类
// func GetInstance() *singleton {
// return s
// }
func GetInstance() Instance {
return s
}
type Instance interface {
Work()
}
1.3、懒汉式单例
非到万不得已不实例化对象
执行过程中与饿汉式的区别为:
- 声明一个全局单例变量,但不进行初始化
- 在GetInstance()方法被调用时,判断单例是否被初始化过,未被初始化则初始化
- 在初始化时,加互斥锁以保证并发安全(可选)
- 使用sync 包下的单例工具 sync.Once可以避免判断加锁逻辑
package singleton
import "sync"
var (
s *singleton
once sync.Once
)
type singleton struct {
}
func newSingleton() *singleton {
return &singleton{}
}
func (s *singleton) Work() {
}
type Instance interface {
Work()
}
func GetInstance() Instance {
once.Do(func() {
s = newSingleton()
})
return s
}