The singleton pattern

The problem

Why have singletons?

The first is that you don’t want to waste resources, and multiple initializations are wasteful. Just use mine for everything. The second is unity. If it is something that needs to be unified, just create a portal so that everyone can only use mine.

implementation

Lazyhead: initialize at use. In case of mandatory unification. Hungrier: Initialize from the start. Heavily used classes for those who don’t want to waste resources.

code

Git address

// Create a Singleton
type Singleton struct{}

var singleton *Singleton
var once sync.Once

//GetInstance is used to get the singleton pattern object
func GetInstance(a) *Singleton {
	once.Do(func(a) {
		singleton = &Singleton{}
	})
	return singleton
}

// This is not the case
type Singleton2 struct{}

var singleton2 *Singleton2

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

// GetInstance Gets an instance
func GetInstance2(a) *Singleton2 {
	return singleton2
}
Copy the code

Unit testing

package singleton

import (
	"sync"
	"testing"
)

const parCount = 100

func TestSingleton(t *testing.T) {
	ins1 := GetInstance()
	ins2 := GetInstance()
	ifins1 ! = 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++ {
		ifinstances[i] ! = instances[i- 1] {
			t.Fatal("instance is not equal")}}}func TestSingleton2(t *testing.T) {
	ins1 := GetInstance2()
	ins2 := GetInstance2()
	ifins1 ! = 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++ {
		ifinstances[i] ! = instances[i- 1] {
			t.Fatal("instance is not equal")}}}Copy the code

Is the singleton pattern perfect?

  • No parameter is supported. It’s my call. Nobody moves.
  • Global variables, if anyone touches them, they blow up.
  • There’s no way to know the internal details. You can only use it, you can’t know the logic.

In fact, all advantages have disadvantages, as long as the scene for their own choice of appropriate mode.