设计模式有创建模式、结构模式、行为模式三类,观察者模式属于行为模式,看一下它的定义:
观察者模式(Observer): 定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。下面看是一个GOLANG的实现:
package observe
import "fmt"
//目标,被观察者
type Subject struct {
observers []Observer //观察者列表
context string //消息
}
func NewSubject() *Subject {
return &Subject{
observers: make([]Observer, 0),
}
}
func (s * Subject)Attach(o Observer) {
s.observers = append(s.observers, o)
}
func (s *Subject )DeAttach(o Observer) {
for i, val := range s.observers {
if val.Name() == o.Name() {
s.observers[i] = s.observers[len(s.observers)-1]
s.observers = s.observers[:len(s.observers)-1]
}
}
}
//通知所有的观察者,可以在这里区别是否发送东西给摸一个观察者。
//这里的通知策略可以给目标添加一个interface,然后不同的通知策略实现不同的类赋值给这个interface就可以了
//当然,也可以在观察者的update函数中忽略不想处理的消息,只处理感兴趣的消息就好了。
func (s *Subject )notify() {
for _, o := range s.observers {
//把整个观察者都发过去了,也可以只发一部分消息,让接受者决定要不要继续拿更多东西
o.Update(s)
}
}
func (s *Subject )UpdateContext(context string) {
s.context = context
s.notify()
}
//只要实现了这个接口就好了
type Observer interface {
Update(*Subject)
Name() string
}
//一个观察者类型
type Reader struct {
name string
}
func NewReader(name string) *Reader {
return &Reader {
name: name,
}
}
func (r *Reader)Update(s *Subject) {
fmt.Printf("%s receive %s\n", r.name, s.context)
}
func (r *Reader)Name( ) string {
return r.name
}
测试文件:
package observe
import "testing"
func TestObserve(t *testing.T) {
//1. 创建一个被观察者
s := NewSubject()
//2. 创建多个观察者
o := NewReader("agan")
//2.1 加进去
s.Attach(o)
//3. 更新被观察者
s.UpdateContext("hello, world!!")
}
输出:
=== RUN TestObserve
agan receive hello, world!!
--- PASS: TestObserve (0.00s)