观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个“观察” 该对象的其他对象
逻辑结构
在观察者模式中,有两个角色:
- Subject(目标): 定义了对象之间的一对多依赖关系。当其状态发生改变时,通知所有注册的观察者对象。
- Observer(观察者): 定义了接收到目标通知时所执行的操作

ConcreteSubject
类与 Observer
接口之间有关联关系。意味着 ConcreteSubject
类通过 RegisterObserver
和 RemoveObserver
方法来管理多个 Observer
观察者对象
代码实现
代码路径:https://github.com/XBoom/DesignPatterns/tree/main/14_Observer
-
首先,定义观察者接口,表示收到目标通知触发更新的接口
1
2
3
4// Observer 观察者接口
type Observer interface {
Update(message string)
} -
其次,定义目标接口,每个目标都可以添加、删除观察者,并可以通知观察者
1
2
3
4
5
6// Subject 被观察者接口
type Subject interface {
RegisterObserver(observer Observer)
RemoveObserver(observer Observer)
NotifyObservers()
} -
接着,实现观察者,也就是收到通知之后触发的业务
1
2
3
4
5
6
7
8// ConcreteObserver 具体观察者
type ConcreteObserver struct {
name string
}
func (co *ConcreteObserver) Update(message string) {
fmt.Printf("[%s] 收到消息:%s\n", co.name, message)
} -
最后,实现目标,目标通知注册的每个观察者。所以目标中有存储观察者们
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// ConcreteSubject 具体被观察者
type ConcreteSubject struct {
observers []Observer //观察者们
}
// RegisterObserver 注册观察者
func (cs *ConcreteSubject) RegisterObserver(observer Observer) {
cs.observers = append(cs.observers, observer)
}
// RemoveObserver 删除观察者
func (cs *ConcreteSubject) RemoveObserver(observer Observer) {
index := -1
for i, obs := range cs.observers {
if obs == observer {
index = i
break
}
}
if index >= 0 {
cs.observers = append(cs.observers[:index], cs.observers[index+1:]...)
}
}
运行逻辑
1 | //定义观察者与被观察者 |
运行结果
1 | [Observer1] 收到消息:Hello, observers! |
总结
- 当一个对象状态的改变需要改变其他对象,或实际对象是事先未知的或动态变化的时
- 当应用中的一些对象必须观察其他对象时,但仅能在有限时间内或特定情况下使用
- 开闭原则。 无需修改发布者代码就能引入新的订阅者类 (如果是发布者接口则可轻松引入发布者类),
channel
也存在类似功能。 - 由于主题和观察者之间的关系是通过接口而不是具体实现建立的,因此它们可以在不同的上下文中重复使用