一、前言
在软件构建过程中,我们需要为某些对象建立一种通知依赖关系,一个对象的状态发生改变,所有依赖对象都将得到通知,如果这样的依赖党关系过于紧密,将使软件不能很好的抵御变化,可以将这种依赖关系弱化,形成一种稳定的依赖关系,从而实现软件体系结构的松耦合。
observer 模式定义对象间的一种一对多(变化)的依赖关系,以便当一个对象的状态发生改变时,所有依赖它的对象都得到通知并自动更新。
二、类图
三、示例
1. 没有使用模式
package main
import (
"fmt"
)
type Anchor struct {
msg string
persons []*Person
}
func (this *Anchor)Attach(ob *Person) {
this.persons = append(this.persons, ob)
}
func (this *Anchor)Detach(ob *Person) {
for index,value := range this.persons {
if value == ob {
this.persons = append(this.persons[:index], this.persons[index+1:]...)
}
}
}
func (this *Anchor)Notify() {
for _, observer := range this.persons {
observer.Update(this.msg)
}
}
func (this *Anchor)setMsg(msg string) {
this.msg = msg
this.Notify()
}
type Person struct {
name string
anchor *Anchor
}
func (this *Person)Update(msg string) {
fmt.Println(this.name+msg)
}
func (this *Person)NewAnchor(name string, subject *Anchor) {
this.name = name
this.anchor = subject
subject.Attach(this)
}
func main() {
anchor := &Anchor{}
person1 := &Person{}
person1.NewAnchor("孙悟空", anchor)
person2 := &Person{}
person2.NewAnchor("猪八戒", anchor)
anchor.setMsg("你好,欢迎订阅!")
anchor.Detach(person1)
anchor.setMsg("你好,欢迎订阅!")
}
当添加一个新的需求时,会违背依赖倒置原则,修改代码也容易造成新的bug
2. 使用模式
package main
import (
"fmt"
)
type Subject interface{
Attach(Observer)
Detach(Observer)
Notify()
}
type SubjectPerson struct {
msg string
observers []Observer
}
func (this *SubjectPerson)Attach(ob Observer) {
this.observers = append(this.observers, ob)
}
func (this *SubjectPerson)Detach(ob Observer) {
for index,value := range this.observers {
if value == ob {
this.observers = append(this.observers[:index], this.observers[index+1:]...)
}
}
}
func (this *SubjectPerson)Notify() {
for _, observer := range this.observers {
observer.Update(this.msg)
}
}
func (this *SubjectPerson)setMsg(msg string) {
this.msg = msg
this.Notify()
}
type Observer interface{
Update(string)
}
type ObserverPerson struct {
name string
subject Subject
}
func (this *ObserverPerson)Update(msg string) {
fmt.Println(this.name+msg)
}
func (this *ObserverPerson)NewObserver(name string, subject Subject) {
this.name = name
this.subject = subject
subject.Attach(this)
}
func main() {
subject := &SubjectPerson{}
observe1 := &ObserverPerson{}
observe1.NewObserver("孙悟空", subject)
observe2 := &ObserverPerson{}
observe2.NewObserver("猪八戒", subject)
subject.setMsg("你好,欢迎订阅!")
subject.Detach(observe1)
subject.setMsg("你好,欢迎订阅!")
}
四、总结
- Observer模式使得我们可以独立的改变目标与观察者,从而使二者之间的关系达到松耦合
- 目标发送通知时,无需指定观察者,通知会自动传播
- 观察者自己决定是否需要订阅通知,目标对象一无所知
- Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的一个重要组成部分