文章目录
一、概述
与其叫他观察者模式,我更愿意叫他叫 订阅-发布模式 ,这种模式在我们生活中非常常见,比如:追番了某个电视剧,当电视剧有更新的时候会第一时间通知你。当你预约了某款游戏后,游戏发布后就会立刻通知你,而不需要你每天都去关注游戏是否上线。
二、示例
我想要说明一点,对于每一种设计模式,最重要的不是代码的结构,而是其中所蕴含的思想,你应该要去考虑的是代码为什么这么设计 ,而不是仅仅照着这样设计,因为每一种设计模式到不同的人手里写出来的代码多多少少会有些许差别,但是其核心的思想是一样的,那就是设计原则
-
分析
此模式需要发布者 及时地通知所有订阅者 ,因此发布者知道所有的订阅者的信息。发布者可以添加或者移除订阅者,订阅者也可以进行订阅或者取消订阅的操作。
-
代码
gopackage main // Publisher 发布者接口 type Publisher interface { AddSubscriber(subscriber Subscriber) // 添加订阅者 RemoveSubscriber(subscriber Subscriber) // 移除订阅者 NotifySubscribers() // 通知订阅者 } // Subscriber 订阅者接口 type Subscriber interface { GetID() string // 获取订阅者ID Notify(contextMessage string) // 通知订阅者 } // Object 被观察者, 实现 Publisher 接口 type Object struct { Subscribers []Subscriber // 订阅者列表 ContextMessage string // 上下文信息 } func (p *Object) AddSubscriber(s Subscriber) { p.Subscribers = append(p.Subscribers, s) } func (p *Object) RemoveSubscriber(s Subscriber) { for i, subscriber := range p.Subscribers { if subscriber.GetID() == s.GetID() { p.Subscribers = append(p.Subscribers[:i], p.Subscribers[i+1:]...) } } } func (p *Object) NotifySubscribers() { for _, subscriber := range p.Subscribers { subscriber.Notify(p.ContextMessage) } } // UpdateContextMessage 更新上下文信息 func (p *Object) UpdateContextMessage(newMessage string) { p.ContextMessage = newMessage p.NotifySubscribers() } // SubscriberA 订阅者A, 实现 Subscriber 接口 type SubscriberA struct { ID string } func (s *SubscriberA) GetID() string { return s.ID } func (s *SubscriberA) Notify(contextMessage string) { println("SubscriberA received:", contextMessage) } // SubscriberB 订阅者B, 实现 Subscriber 接口 type SubscriberB struct { ID string } func (s *SubscriberB) GetID() string { return s.ID } func (s *SubscriberB) Notify(contextMessage string) { println("SubscriberB received:", contextMessage) } func main() { // 创建被观察者 object := Object{} // 创建订阅者 subscriberA := SubscriberA{ID: "subscriberA"} subscriberB := SubscriberB{ID: "subscriberB"} // 添加订阅者 A 和 B object.AddSubscriber(&subscriberA) object.AddSubscriber(&subscriberB) // 更新上下文信息, 通知所有订阅者 object.UpdateContextMessage("Hello World!") // 移除订阅者B object.RemoveSubscriber(&subscriberB) // 更新上下文信息, object.UpdateContextMessage("Hello World Again!") }
上述代码还没有一些没有去做,建议你可以尝试去实现:
- 订阅者能够主动的订阅或者取消订阅,建议你尝试着去完成这一功能
- 通知顺序是有序/无需的
三、模式定义
观察者模式定义了对象之间的一对多依赖,这样一来每当一个对象改变状态时,他所所有的依赖者都会收到通知并自动更新。
四、其他
java 中也有内置的观察者模式。java.util 包内包含最基本的 Observer
接口和 Observable
类,如果有兴趣可以去了解一下其运作方式。