【go写设计模式】单例模式--全都用我的

单例模式

问题

为什么要有单例模式?

第一是不想浪费资源,多次初始化会造成浪费。都用我的就好了。
其次是统一,如果是需要统一的东西,那就只创立一个入口,让大家只能用我的。

实现

懒汉式:在使用的时候再初始化。针对要强制统一的情况。
饿汉式:最开始就初始化。针对不想浪费资源的情况,是大量使用的类。

代码

Git地址

//Singleton 懒汉式单例
type Singleton struct{
    
    }

var singleton *Singleton
var once sync.Once

//GetInstance 用于获取单例模式对象
func GetInstance() *Singleton {
    
    
	once.Do(func() {
    
    
		singleton = &Singleton{
    
    }
	})
	return singleton
}

// Singleton2 饿汉式单例
type Singleton2 struct{
    
    }

var singleton2 *Singleton2

func init() {
    
    
	singleton2 = &Singleton2{
    
    }
}

// GetInstance 获取实例
func GetInstance2() *Singleton2 {
    
    
	return singleton2
}

单元测试

package singleton

import (
	"sync"
	"testing"
)

const parCount = 100

func TestSingleton(t *testing.T) {
    
    
	ins1 := GetInstance()
	ins2 := GetInstance()
	if ins1 != ins2 {
    
    
		t.Fatal("instance is not equal")
	}
}

func TestParallelSingleton(t *testing.T) {
    
    
	wg := sync.WaitGroup{
    
    }
	wg.Add(parCount)
	instances := [parCount]*Singleton{
    
    }
	for i := 0; i < parCount; i++ {
    
    
		go func(index int) {
    
    
			instances[index] = GetInstance()
			wg.Done()
		}(i)
	}
	wg.Wait()
	for i := 1; i < parCount; i++ {
    
    
		if instances[i] != instances[i-1] {
    
    
			t.Fatal("instance is not equal")
		}
	}
}

func TestSingleton2(t *testing.T) {
    
    
	ins1 := GetInstance2()
	ins2 := GetInstance2()
	if ins1 != ins2 {
    
    
		t.Fatal("instance is not equal")
	}
}

func TestParallelSingleton2(t *testing.T) {
    
    
	wg := sync.WaitGroup{
    
    }
	wg.Add(parCount)
	instances := [parCount]*Singleton2{
    
    }
	for i := 0; i < parCount; i++ {
    
    
		go func(index int) {
    
    
			instances[index] = GetInstance2()
			wg.Done()
		}(i)
	}
	wg.Wait()
	for i := 1; i < parCount; i++ {
    
    
		if instances[i] != instances[i-1] {
    
    
			t.Fatal("instance is not equal")
		}
	}
}

单例模式是完美的?

  • 不支持带参数。都是我说了算,谁也别想动。
  • 全局的变量,万一有人乱动,就炸了。
  • 无法知道内部细节。也就是只能用,不能知道里面的逻辑。

其实凡是有利就有弊,只要针对自己的场景选择合适的模式就好了。

猜你喜欢

转载自blog.csdn.net/happy_teemo/article/details/112714346