单例模式是我们工作中最长用到的设计模式之一,单例模式也是创建型设计模式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
通过单例模式可以保证系统中一个类只有一个实例且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
单例模式一般分为两种实现方式:懒汉模式和饿汉模式
饿汉模式
表示程序在初始化阶段或使用前已创建出了一个实例,在程序后面的生命生命周期内将不再创建
// 声明一个结构体
type IPhone struct {
Version int
}
// 用来存储IPhone的实例
var iphone *IPhone
// init函数保证了GetInstance()被调用前完成对象初始化 或可以直接 var iphone = &IPhone{}
func init() {
iphone = &IPhone{Version: 7}
// 输出iphoen对象指针地址
fmt.Printf("初始化iphone指针:%p \n", iphone)
}
// 获取IPhone的实例
func GetInstance() *IPhone {
return iphone
}
测试
func main() {
// 第一次获取实例
iphone1 := GetInstance()
// 验证获取到了实例
fmt.Printf("这是IPhone%v \n", iphone1.Version)
// 第二次获取实例
iphone2 := GetInstance()
//输出两次实例的指针地址,判断是否是同一个对象
fmt.Printf("iphone1指针:%p \n", iphone1)
fmt.Printf("iphone2指针:%p", iphone2)
}
运行结果
可以看到我们的实例获取成功,并输出其Version字段。对比3个指针地址一都是相同的,说明通过GetInstance()方法获取到的是同一个实例
懒汉模式
懒汉模式,顾名思义就是懒,没有对象需要调用它的时候不去实例化,有人来向它要对象的时候再实例化对象
import (
"fmt"
"sync"
)
type IPhone struct {
Version int
}
// 用来存储IPhone的实例
var iphone *IPhone
// once.Do可以保证函数只可能执行一次,防止高并发场景下多次执行实例化方法
var once sync.Once
func GetInstance() *IPhone {
if iphone == nil {
once.Do(func() {
iphone = &IPhone{Version: 13}
// 输出iphoen对象指针地址
fmt.Printf("初始化iphone指针:%p \n", iphone)
})
}
return iphone
}
测试
测试可使用上面相同的代码。我们直接看运行结果
结果符合我们的预期
代码已上传Github:LyonNee/design_patterns_with_go: 基于Golang实现的设计模式代码 (github.com)