模式定义
定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者都会收到告诉并更新
类图
利用场景
当更改一个对象的状态可能须要更改其余对象,并且理论的对象当时未知或动静更改时,应用观察者模式
长处
1.合乎开闭准则
2.能够在运行时建设对象之间的关系
要点总结
- 应用面向对象的形象,Observe模式使得咱们能够独立地扭转指标与观察者,从而使二者之间的依赖关系达到松耦合
- 指标发送告诉时,无需指定观察者,告诉(能够携带告诉信息作为参数)会主动流传
- 观察者本人解决是否须要订阅告诉,指标对象对此无所不知
- Observer模式是基于事件的UI框架中十分罕用的设计模式,也是MVC模式的一个重要组成部分
Go语言代码实现
工程目录
observe.go
package Observer import ( "fmt" "sync" "time" ) type Event struct { Data int } type Observer interface { NotifyCallback(event Event) } type Subject interface { AddListener(observer Observer) RemoveListener(observer Observer) Notify(event Event) } type eventObserver struct { ID int Time time.Time } type eventSubject struct { Observers sync.Map } func (e eventObserver) NotifyCallback(event Event) { fmt.Printf("Recieved:%d after %v\n", event.Data, time.Since(e.Time)) } func (e *eventSubject) AddListener(obs Observer) { e.Observers.Store(obs, struct{}{}) } func (e *eventSubject) RemoveListener(obs Observer) { e.Observers.Delete(obs) } func (e *eventSubject) Notify(event Event) { e.Observers.Range(func(key, value interface{}) bool { if key == nil { return false } key.(Observer).NotifyCallback(event) return true }) } func Fib(n int) chan int { out := make(chan int) go func() { defer close(out) for i, j := 0, 1; i < n; i, j = i+j, i { out <- i } }() return out }
observer_test.go
package Observer import ( "sync" "testing" "time" ) func TestFib(t *testing.T) { //for x := range Fib(10) { // fmt.Println(x) //} n := eventSubject{Observers: sync.Map{}} obs1 := eventObserver{ID: 1, Time: time.Now()} obs2 := eventObserver{ID: 2, Time: time.Now()} n.AddListener(obs1) n.AddListener(obs2) for x := range Fib(10) { n.Notify(Event{Data: x}) } }