大家好,我是砸锅。一个摸鱼八年的后端开发。熟悉 Go、Lua。今天和大家一起学习设计模式😊
单例模式
单例模式(Singleton Pattern)是一种常见的设计模式。单例模式的类提供了一种访问其唯一对象的方法,该对象可以直接被访问,无须实例化。单例模式保证该类的对象只存在一个,同时维护该对象的全局访问点
单例模式的使用场景
- 程序中某个类需要对所有客户端都只有一个可用实例,则可以使用单例模式
- 更严格控制全局变量,则可以使用单例模式
- 程序处理日志记录的实例,可以使用单例模式
- 创建读取程序的配置对象,可以使用单例模式
Go 单例模式的实现方式
- 懒汉式单例模式
- 饿汉式单例模式
- 双重检查单例模式
- sync.Once 单例模式
懒汉式单例模式
在创建对象时,不直接创建对象,而是在加载配置文件时才创建对象
package main
import "sync"
// 单例类
type singleton struct {
value int
}
// 声明私有变量
var instance *singleton
// 声明锁对象,通过加锁的方式保证了协程的并发安全,但是每次调用都需要加锁,性能上不够高效
var mutex sync.Mutex
func GetInstance() *singleton {
mutex.Lock()
defer mutex.Unlock()
if instance == nil {
instance = new(singleton)
}
return instance
}
func main() {
}
饿汉式单例模式
在创建对象时,不判断创建的对象是否为空,直接创建对象。饿汉式单例模式是并发安全的,缺点是在导入包时会创建对象并且持续存储在内存中
package main
import "fmt"
type singleton struct{}
var instance *singleton
func init() {
if instance == nil {
instance = new(singleton)
fmt.Println("创建单个实例")
}
}
// 提供获取实例的函数
func GetInstance() *singleton {
return instance
}
双重检查单例模式
在懒汉式单例模式的基础上优化,减少加锁操作
package main
import (
"fmt"
"sync"
)
// 单例类
type singleton struct {
value int
}
// 声明私有变量
var instance *singleton
// 声明锁对象,通过加锁的方式保证了协程的并发安全
var mutex sync.Mutex
func GetInstance() *singleton {
// 当对象为空时,对对象加锁;在创建好对象之后,在获取对象就不需要加锁
if instance == nil {
mutex.Lock()
if instance == nil {
instance = new(singleton)
fmt.Println("创建单个实例")
}
mutex.Unlock()
}
return instance
}
func main() {
}
sync.Once 单例模式
sync.Once 可以在代码任意位置被初始化和调用,在并发场景是安全的
package main
import (
"fmt"
"sync"
)
type singleton struct{}
var instance *singleton
var once sync.Once
func GetInstance() *singleton {
once.Do(func() {
instance = new(singleton)
fmt.Println("创建单个实例")
})
return instance
}
func main() {
}
此文章为4月Day7学习笔记,内容来源于极客时间《设计模式之美》 这门课真的非常好,推荐大家看看