1. 什么是监听者模式
监听者模式的作用是在对象之间定义一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在代码中,被监听者接口定义了添加、删除和通知监听者的方法,而监听者接口定义了更新方法。
2. 监听者模式使用的场景
- 当一个对象的改变需要同时改变其他对象的时候,或者当一个对象的改变需要通知其他对象,而又不希望和被通知的对象形成紧耦合关系的时候。
- 当一个对象需要将自己的改变通知其他对象,而它又不需要知道其他对象的细节的时候。
- 当一个对象需要通知其他对象,而这些对象又不需要知道通知的来源对象的时候。
在实际开发中,监听者模式常用于事件处理、GUI 系统、网络编程等场景。
3. golang实现监听者
- 模拟场景
- 实现两个监听对象,当服务发生通知时,两个监听者收到通知信息;
- 移除一个监听者2,再次发生通知。只有监听者1接受到信息。
package main
import "fmt"
// 定义一个监听者接口
type Observer interface {
Update(string)
}
// 定义一个被监听者接口
type Subject interface {
AddObserver(Observer)
RemoveObserver(Observer)
Notify(string)
}
// 实现被监听者接口
type ConcreteSubject struct {
observers []Observer
}
func (cs *ConcreteSubject) AddObserver(observer Observer) {
cs.observers = append(cs.observers, observer)
}
func (cs *ConcreteSubject) RemoveObserver(observer Observer) {
for i, o := range cs.observers {
if o == observer {
cs.observers = append(cs.observers[:i], cs.observers[i+1:]...)
break
}
}
}
func (cs *ConcreteSubject) Notify(msg string) {
for _, o := range cs.observers {
o.Update(msg)
}
}
// 实现监听者接口
type ConcreteObserver struct {
name string
}
func (co *ConcreteObserver) Update(msg string) {
fmt.Printf("%s receive message: %s\n", co.name, msg)
}
func main() {
subject := &ConcreteSubject{}
observer1 := &ConcreteObserver{name: "observer1"}
observer2 := &ConcreteObserver{name: "observer2"}
subject.AddObserver(observer1)
subject.AddObserver(observer2)
subject.Notify("hello")
subject.RemoveObserver(observer2)
subject.Notify("world")
}
- 输出结果
observer1 receive message: hello
observer2 receive message: hello
observer1 receive message: world