package observer import "sync" type ( Event string OnNotify func(data interface{}, args ...interface{}) Listener struct { OnNotify OnNotify } Observer interface { AddListener(event Event, listener Listener) Remove(event Event) Notify(event Event, data interface{}, args ...interface{}) } ObserverImpl struct { listeners map[Event][]Listener } ) var ( obs *ObserverImpl singletonObserver sync.Once ) func NewObserver() *ObserverImpl { singletonObserver.Do(func() { obs = &ObserverImpl{} }) return obs } func (o *ObserverImpl) AddListener(event Event, listener Listener) { if o.listeners == nil { o.listeners = map[Event][]Listener{} } o.listeners[event] = append(o.listeners[event], listener) } func (o *ObserverImpl) Remove(event Event) { delete(o.listeners, event) } func (o *ObserverImpl) Notify(event Event, data interface{}, args ...interface{}) { if listeners, ok := o.listeners[event]; !ok { return } else { for _, listener := range listeners { go listener.OnNotify(data, args...) } } }