pengpengyangyang的博客
观察者模式

观察者模式用于触发联动。

当中心点发生变化时,调用所有观察者的回调函数。回调函数由观察者实现,和中心点无关,中心点只管触发。

package observer

import (
	"sync"
)

// Subject 观察者模式,Subject对象可触发其他观察者的动作
type Subject struct {
	observers map[string]Observer
	mutex     sync.Mutex
	context   string
}

func NewSubject() *Subject {
	return &Subject{
		observers: make(map[string]Observer, 0),
	}
}

// Attach 增加观察者
func (s *Subject) Attach(key string, o Observer) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	s.observers[key] = o
}

// Remove 删除观察者
func (s *Subject) Remove(key string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	delete(s.observers, key)
}

// UpdateContext 向观察者发送信号,触发动作
func (s *Subject) UpdateContext(context string) {
	s.context = context
	s.notify()
}

func (s *Subject) notify() {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	for _, o := range s.observers {
		go o.Update(s)
	}
}

// Observer 观察者接口,Update为被触发时执行的函数
type Observer interface {
	Update(*Subject)
}

type Reader struct {
	name   string
	Notify chan string
}

func NewReader(name string) *Reader {
	return &Reader{
		name:   name,
		Notify: make(chan string),
	}
}

func (r *Reader) Update(s *Subject) {
	r.Notify <- s.context
}