Go设计模式:单例模式

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	// 演示懒汉式
	go func() {
		s := NewLazySingleton()
		s.Say()
	}()
	singleton := NewLazySingleton()
	singleton.Say()

	// 演示饿汉式
	go func() {
		h := NewHungrySingleton()
		h.Say()
	}()
	hungry := NewHungrySingleton()
	hungry.Say()

	time.Sleep(time.Second)
}

// 定义一个结构体(至关于面向对象语言里面的class)
type Singleton struct {
	name string
}

// 至关于class的方法
func (s Singleton) Say() {
	fmt.Printf("%s: Say Hello\n", s.name)
}

// 因为Go并非彻底面向对象的语言,只能经过包级别的全局变量模拟类变量
var lazyInstance *Singleton

// 为了Go协程并发安全,能够加锁,若是不加锁第一次实例化的时候会出现data race操做,可是其实并不影响功能
// 第一加锁方式是使用mutex
// mu.lock
// defer mu.unlock
// 可是这样并不优雅,至关于每次New的时候都得加锁,影响性能,因此最好的方式是使用once
var once sync.Once

// 懒汉式,所谓懒汉式就是比较懒,等你第一次调用的时候才会去实例化对象
func NewLazySingleton() *Singleton {
	once.Do(func() {
		fmt.Println("init lazy")
		lazyInstance = &Singleton{name: "lazy"}
	})
	return lazyInstance
}

var hungryInstance = Singleton{name: "hungry"}

// 饿汉式,所谓饿汉式就是在你调用New以前就已经初始化好了,这个更简单,并且也不须要锁
func NewHungrySingleton() *Singleton {
	return &hungryInstance
}
复制代码

单例模式在实际开发中用的仍是比较的多,好比数据库链接池、配置文件等数据库

相关文章
相关标签/搜索