【Go-设计模式】观察者模式 详解
概念:
观察者模式 用于 触发联动
一个对象的改变 会触发 其它观察者的相关动作,而 此对象 无需关心 联动对象 的 具体实现
对象之间 多对一依赖 的一种设计方案,被依赖的对象 为 Subject,依赖的对象 为 Observer,Subject 通知 Observer 变化
UML:
- Subject:
抽象主题角色,把所有对 观察者对象的引用 保存在一个 集合 中。
抽象主题 提供一个 接口,可以 增加 和 删除 观察者对象,
抽象主题角色 又叫做 抽象被观察者(Observable)角色 - ConcreteSubject:
将 有关状态 存入 具体观察者对象
在具体主题的 内部状态 改变 时,给 所有登记过 的 观察者 发出通知
具体主题角色 又叫做 具体被观察者(Concrete Observable)角色。 - Observer:
为 所有的具体观察者 定义一个 接口,在 得到主题的通知 时 触发动作 - ConcreteObserver:
存储 与 主题的状态 符合 的状态
具体观察者角色 实现 抽象观察者角色 所要求的 触发动作具体实现
示例:
被观察者 功能接口:
type Subject interface {
RegisterObserver(observer Observer)
RemoveObserver(observer Observer)
NotifyObservers(message string)
}
被观察者 具体实现:
type ConcreteSubject struct {
message string
observerSet map[Observer]struct{}
}
func (this *ConcreteSubject) RegisterObserver(observer Observer) {
this.observerSet[observer] = struct{}{}
}
func (this *ConcreteSubject) RemoveObserver(observer Observer) {
delete(this.observerSet, observer)
}
func (this *ConcreteSubject) NotifyObservers(message string) {
for observer := range this.observerSet {
notifyMessage := fmt.Sprintf("【ConcreteSubject】message: %v", message)
observer.Update(notifyMessage)
}
}
func NewConcreteSubject() ConcreteSubject {
return ConcreteSubject{
observerSet: map[Observer]struct{}{},
}
}
观察者 功能接口:
type Observer interface {
Update(message string)
}
观察者 具体实现:
具体实现1:
type ConcreteObserver1 struct {
message string
}
func (this *ConcreteObserver1) Update(message string) {
this.message = message
this.display()
}
func (this *ConcreteObserver1) display() {
recievedMessage := fmt.Sprintf("*** 具体观察者1,收到的信息为:%v ***", this.message)
fmt.Println(recievedMessage)
}
具体实现2:
type ConcreteObserver2 struct {
message string
}
func (this *ConcreteObserver2) Update(message string) {
this.message = message
this.display()
}
func (this *ConcreteObserver2) display() {
recievedMessage := fmt.Sprintf("*** 具体观察者2,收到的信息为:%v ***", this.message)
fmt.Println(recievedMessage)
}
测试:
package main
import (
"DemoProject/design/base23/observer" // 根据自己的项目路径定制
"fmt"
)
func main() {
// observer
subject := observer.NewConcreteSubject()
observer1 := observer.ConcreteObserver1{}
observer2 := observer.ConcreteObserver2{}
fmt.Println("============ register observe ============")
subject.RegisterObserver(&observer1)
subject.RegisterObserver(&observer2)
subject.NotifyObservers("Youzg is a good man!")
fmt.Println("============ remove observe ============")
subject.RemoveObserver(&observer1)
subject.NotifyObservers("And Youzg is so cool!")
}
注意事项:
观察者模式中,会以 集合 的方式来 管理 观察者(Observer),包括 注册、移除 和 通知
增加观察者 不需要去 修改核心类 ConcreteSubject, 遵守了 ocp(开闭原则)原则