singleton

package module
v0.0.0-...-404efc1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 29, 2021 License: MIT Imports: 1 Imported by: 0

README

Паттерн «Одиночка»

Одиночка (англ. Singleton) — шаблон проектирования, гарантирующий, что у типа есть только один экземпляр, предоставляющий глобальную точку доступа к нему.

Реализация (см. код)

type Singleton interface {
  AddOne() int
}

type singleton struct {
  count int
}

var instance *singleton

func GetInstance() Singleton {
  if instance == nil {
    instance = &singleton{}
  }
  return instance
}

func (s *singleton) AddOne() int {
  s.count++
  return s.count
}

Проблема этой реализации становится сразу очевидна, функция GetInstance и метод AddOne подвержены ошибкам конкурентного доступа.

Исправление ошибки

Сначала разберемся с GetInstance. Здесь можно попробовать исправить эту ошибку с помощью блокировок

var mu sync.Mutex

func GetInstance() Singleton {
  mu.Lock()
  defer mu.Unlock

  if instance == nil {
    instance = &singleton{}
  }
  return instance
}

Но в стандартной библиотеке Golang есть sync.Once, который способен вызывать функцию только один раз

var once sync.Once

func GetInstance() Singleton {
  once.Do(func() {
    instance = &singleton{}
  })

  return instance
}

Теперь AddOne. Есть сейчас запустить текст TestParallel из файла singleton_test.go, то ожидая получить 10000, мы получим гораздо меньше. Если запустить тест с -race, то мы увидем множество DATA RACE ошибок.

Чтобы исправить это, мы можем использовать бинарный семафор, он же мьютекс

type singleton struct {
   count int
   sync.RWMutex
}

func (s *singleton) AddOne() {
   s.Lock()
   defer s.Unlock()
   s.count++
}

func (s *singleton) GetCount()int {
   s.RLock()
   defer s.RUnlock()
   return s.count
}

Дополнительная информация

Все материалы взяты отсюда

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Singleton

type Singleton interface {
	AddOne() int
	GetCount() int
}

func GetInstance

func GetInstance() Singleton

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL