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

Posted 0pandas0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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
", 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

以上是关于[01]Go设计模式:单例模式(Singleton)的主要内容,如果未能解决你的问题,请参考以下文章

Go设计模式之单例模式

Go 单例模式

Go 单例模式

JavaSE面试题——Singleton单例模式的几种写法

2016.01.22 单例模式(Singleton)

单例模式(singleton)之“世上安得双全法”