[01]Go设计模式:单例模式(Singleton)

单例模式

一、简介

单例模式(Singleton Pattern)是软件设计中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

二、代码实现

1、懒汉模式

非线程安全。当正在创建时,有线程来访问此时LazyInstance = nil就会再创建,单例类就会有多个实例了。

var LazyInstance *Instance

func GetLazyInstance() *Instance {
	if LazyInstance == nil {
		LazyInstance = &Instance{
			Counter: 0,
			Name:    "LazyInstance",
		}
	}
	return LazyInstance
}

2、饿汉模式

初始化比较耗时间的话,获取的性能比较慢

var HungryInstance = &Instance{Name: "HungryInstance", Counter: 0}
func GetHungryInstance() *Instance {
	return HungryInstance
}

3、改进型懒汉模式

每次读取都加锁了,比较好性能,更多的时候获取是不用加锁的

var mu sync.Mutex
var LazyInstancePlus *Instance
func GetLazyInstancePlus() *Instance {
	mu.Lock()
	defer mu.Unlock()
	if LazyInstancePlus == nil {
		LazyInstancePlus = &Instance{
			Counter: 0,
			Name:    "LazyInstancePlus",
		}
	}
	return LazyInstancePlus
}

只为空的时候加锁,提高了性能

var LazyInsPlusPlus *Instance

func GetLazyInsPlusPlus() *Instance {
	if LazyInsPlusPlus == nil {
		mu.Lock()
		defer mu.Unlock()
		LazyInsPlusPlus = &Instance{
			Counter: 0,
			Name:    "LazyInsPlusPlus",
		}
	}
	return LazyInsPlusPlus
}

4、 sync.once实现

var once sync.Once
var SyncOnceInstance *Instance

func GetInstanceSyncOnce() *Instance {
	once.Do(func() {
		SyncOnceInstance = &Instance{
			Counter: 0,
			Name:    "SyncOnceInstance",
		}
	})
	return SyncOnceInstance
}

5、测试用例

package main

import (
	"fmt"
	"sync"
)

type Instance struct {
	Name    string
	Counter int //详细参数
}

func (i *Instance) Hello() {
	fmt.Printf("%s: my current counter is:%d\n", i.Name, i.Counter)
}

//省略实现
func main() {
	//懒汉模式测试
	ls := GetLazyInstance()
	ls.Hello()
	ls.Counter += 1
	ls1 := GetLazyInstance()
	ls1.Hello()

	//饿汉模式测试
	hs := GetHungryInstance()
	hs.Hello()
	hs.Counter += 10
	hs1 := GetHungryInstance()
	hs1.Hello()

	//改进型懒汉模式
	lsp := GetLazyInstancePlus()
	lsp.Hello()
	lsp.Counter += 100
	lsp1 := GetLazyInstancePlus()
	lsp1.Hello()

	lspp := GetLazyInsPlusPlus()
	lspp.Hello()
	lspp.Counter += 1000
	lspp1 := GetLazyInsPlusPlus()
	lspp1.Hello()

	//sync once 测试
	sc := GetInstanceSyncOnce()
	sc.Hello()
	sc.Counter += 10000
	sc1 := GetInstanceSyncOnce()
	sc1.Hello()

}

结果:

LazyInstance: my current counter is:0
LazyInstance: my current counter is:1
HungryInstance: my current counter is:0
HungryInstance: my current counter is:10
LazyInstancePlus: my current counter is:0
LazyInstancePlus: my current counter is:100
LazyInsPlusPlus: my current counter is:0
LazyInsPlusPlus: my current counter is:1000
SyncOnceInstance: my current counter is:0
SyncOnceInstance: my current counter is:10000

完整代码和测试用例: https://gitee.com/ncuzhangben/GoStudy/tree/master/go-design-pattern/01-Singleton

posted @ 2019-12-13 17:41  0pandas0  阅读(373)  评论(2编辑  收藏  举报