Skip to Content

Singleton

Muammo: ba’zi obyektlar butun dastur bo’yicha faqat bitta nusxada bo’lishi kerak — config, ma’lumotlar bazasi puli (pool), logger. Bir nechta goroutine uni bir vaqtda so’rab qolsa, ehtiyot bo’lmasang, ikkita nusxa yaratib qo’yish xavfi bor (race condition).

G’oya: Go’da eng toza yechim — sync.Once. Uning Do metodiga bergan funksiyang, uni nechta goroutine chaqirmasin, roppa-rosa bir marta ishlaydi. Qolganlari birinchisi tugaguncha kutib turadi.

singleton.go
package main import ( "fmt" "sync" ) type Config struct { values map[string]string } var ( instance *Config once sync.Once ) func GetConfig() *Config { once.Do(func() { fmt.Println("Config yaratilyapti (faqat bir marta)") instance = &Config{values: map[string]string{"port": "8080"}} }) return instance } func main() { var wg sync.WaitGroup for i := range 5 { wg.Add(1) go func(n int) { defer wg.Done() fmt.Printf("goroutine %d -> port=%s\n", n, GetConfig().values["port"]) }(i) } wg.Wait() fmt.Println("bir xil obyektmi:", GetConfig() == GetConfig()) }
$ go run singleton.go Config yaratilyapti (faqat bir marta) goroutine 4 -> port=8080 goroutine 2 -> port=8080 goroutine 3 -> port=8080 goroutine 0 -> port=8080 goroutine 1 -> port=8080 bir xil obyektmi: true

“Config yaratilyapti” bir marta chiqadi; goroutinelarning chiqish tartibi esa har safar boshqacha bo’lishi mumkin.

Qachon: rostdan ham global va o’zgarmas resurslar uchun. Singleton — aslida yashiringan global holat (state): u testlashni qiyinlashtiradi, shuning uchun Go’da ko’pincha obyektni mainda yaratib, uni argument sifatida uzatish (dependency injection) afzalroq.

Manba / batafsil: refactoring.guru/design-patterns/singleton 

Last updated on