1、原理
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式(Observer)又称发布-订阅模式(Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方(被观察方)和接收通知的一方(观察者)能彼此分离,互不影响。
在最基础的观察者模式中,包括以下四个角色:
被观察者:从类图中可以看到,类中有一个用来存放观察者对象的Vector容器(之所以使用Vector而不使用List,是因为多线程操作时,Vector在是安全的,而List则是不安全的),这个Vector容器是被观察者类的核心,另外还有三个方法:attach方法是向这个容器中添加观察者对象;detach方法是从容器中移除观察者对象;notify方法是依次调用观察者对象的对应方法。这个角色可以是接口,也可以是抽象类或者具体的类,因为很多情况下会与其他的模式混用,所以使用抽象类的情况比较多。
观察者:观察者角色一般是一个接口,它只有一个update方法,在被观察者状态发生变化时,这个方法就会被触发调用。
具体的被观察者:使用这个角色是为了便于扩展,可以在此角色中定义具体的业务逻辑。
具体的观察者:观察者接口的具体实现,在这个角色中,将定义被观察者对象状态发生变化时所要处理的逻辑。
2、示例
示例代码:
package main
import "fmt"
type Observer interface {
Update(subject *Subject)
}
type Subject struct {
observers []Observer
msg string
}
//添加观察者
func (s *Subject) Attach(o Observer) {
s.observers = append(s.observers, o)
}
//通知信息到观察者
func (s *Subject) Notify() {
for _, o := range s.observers {
o.Update(s) //调用接口对应的方法
}
}
//更新信息
func (s *Subject) UpdateMsg(context string) {
s.msg = context
s.Notify()
}
func NewSubject()*Subject {
return &Subject{
observers: make([]Observer,0),
msg: "",
}
}
//=======信息接受者======
type Reader struct {
name string
}
func (r *Reader) Update(s *Subject) {
fmt.Printf("【%s】收到的信息:%v\n", r.name, s.msg)
}
func NewReader(name string) *Reader {
return &Reader{name: name}
}
func main() {
subject := NewSubject()
r1 := NewReader("张三")
r2 := NewReader("李四")
r3 := NewReader("王五")
subject.Attach(r1)
subject.Attach(r2)
subject.Attach(r3)
subject.UpdateMsg("MM来了")
//subject.Notify()
r4:=NewReader("赵六")
subject.Attach(r4) //添加新的观察者
subject.UpdateMsg("好漂亮")
}
UML图: