《设计模式之美》 学习笔记 day2

86 阅读2分钟

大家好,我是砸锅。一个摸鱼八年的后端开发。熟悉 Go、Lua。今天和大家一起学习设计模式😊

单例模式

单例模式(Singleton Pattern)是一种常见的设计模式。单例模式的类提供了一种访问其唯一对象的方法,该对象可以直接被访问,无须实例化。单例模式保证该类的对象只存在一个,同时维护该对象的全局访问点

单例模式的使用场景

  1. 程序中某个类需要对所有客户端都只有一个可用实例,则可以使用单例模式
  2. 更严格控制全局变量,则可以使用单例模式
  3. 程序处理日志记录的实例,可以使用单例模式
  4. 创建读取程序的配置对象,可以使用单例模式

Go 单例模式的实现方式

  1. 懒汉式单例模式
  2. 饿汉式单例模式
  3. 双重检查单例模式
  4. 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学习笔记,内容来源于极客时间《设计模式之美》 这门课真的非常好,推荐大家看看