单例模式
问题
为什么要有单例模式?
第一是不想浪费资源,多次初始化会造成浪费。都用我的就好了。
其次是统一,如果是需要统一的东西,那就只创立一个入口,让大家只能用我的。
实现
懒汉式:在使用的时候再初始化。针对要强制统一的情况。
饿汉式:最开始就初始化。针对不想浪费资源的情况,是大量使用的类。
代码
//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")
}
}
}
单例模式是完美的?
- 不支持带参数。都是我说了算,谁也别想动。
- 全局的变量,万一有人乱动,就炸了。
- 无法知道内部细节。也就是只能用,不能知道里面的逻辑。
其实凡是有利就有弊,只要针对自己的场景选择合适的模式就好了。