Observer Pattern with Channels
Kanallar bilan Observer naqshi
YouTube kanaliga obuna bo'lganingizni tasavvur qiling: kanal egasi yangi video joylashtirganda, barcha obunachilar avtomatik xabar oladi — kanal egasi har bir obunachiga alohida qo'ng'iroq qilib aytib chiqmaydi. Observer (kuzatuvchi) naqshi — aynan shu: bitta "voqea manbai" bor, va unga "obuna bo'lgan" bir nechta tomon shu voqeadan avtomatik xabardor bo'ladi.
Boshqa tillarda bu naqsh odatda ro'yxatga qo'shilgan "listener" obyektlar orqali amalga oshiriladi. Go'da esa bizda tabiiy, o'zi bilan xabar yetkazadigan vosita bor — kanallar. Har bir "obunachi" o'zining shaxsiy kanalini oladi, va "nashriyot" voqea sodir bo'lganda shu kanallarning barchasiga xabar yuboradi.
package main
import "fmt"
type EventBus struct {
subscribers []chan string
}
func (b *EventBus) Subscribe() <-chan string {
ch := make(chan string, 1)
b.subscribers = append(b.subscribers, ch)
return ch
}
func (b *EventBus) Publish(event string) {
for _, ch := range b.subscribers {
ch <- event
}
}
func main() {
bus := &EventBus{}
aziz := bus.Subscribe()
bobur := bus.Subscribe()
bus.Publish("buyurtma yaratildi")
fmt.Println(<-aziz)
fmt.Println(<-bobur)
}Subscribe() chaqirilganda, EventBus yangi kanal yaratadi, uni o'zining ichki ro'yxatiga qo'shadi, va shu kanalni chaqiruvchiga faqat o'qish uchun (<-chan string) qaytaradi — chaqiruvchi u yerga o'zi yozolmaydi, faqat o'qiy oladi ("Channel Directions" darsini eslang). Publish chaqirilganda esa, EventBus barcha obunachilarning kanaliga xabarni yuboradi.
Bufer hajmi (make(chan string, 1)) muhim: agar kanal buferlanmagan bo'lsa, Publish ichidagi ch <- event — obunachi shu paytning o'zida o'qishga tayyor bo'lmasa, bloklanib qolardi (butun nashriyot to'xtab qolardi). Kichik bufer bilan, Publish xabarni "qo'yib", darhol davom etadi, obunachi esa o'ziga qulay vaqtda o'qib oladi.
>_ Exercise
EventBus'ga obunachilar sonini bilish imkonini qo'shing.
- •SubscriberCount() int metodini yozing: obunachilar sonini qaytaring
- •uchta obunachi (Subscribe) qo'shib, SubscriberCount() ni chop eting
- •"yangilanish" xabarini Publish qilib, birinchi obunachidan o'qib chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Go'da Observer naqshini amalga oshirish uchun maxsus "listener" interfeysi shart emas — har bir obunachiga alohida kanal berish orqali, kanallarning o'zi xabar yetkazish vositasi bo'lib xizmat qiladi.
NEXT UP
Decorator Pattern
$ go run main.go
Kodingizni ishga tushiring