观察者模式
是一种行为型模式,其定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。
观察者模式常用 订阅/发布机制
,即发布者持有所有订阅者,当发布者状态变更或者特定行为时,通知所有订阅者。
结构
- 1.发布者。属性及行为:属性,订阅者列表,行为,添加、删除订阅者方法,在自身状态改变或特定行为发生时通知订阅者。
- 2.抽象订阅者,声明update更新方法。
- 3.具体订阅者,通知时执行方法。
- 4.客户端,分别创建发布者订阅者对象,并且为发布者添加订阅者对象。
优缺点
- 优点
1.开闭原则。无需修改发布者代码就能引入新的订阅者类。
2.可以在运行时建立对象之间的联系。
- 缺点
1.订阅者的通知顺序是随机的。
个人理解,如果订阅者是列表,执行通知 Notify()
是遍历列表的话,应该有顺序
适用场景
- 1.当一个对象状态的改变需要改变其他对象, 或实际对象是事先未知的或动态变化的时。
- 2.当应用中的一些对象必须观察其他对象时, 可使用该模式。
代码实现
package main
import "fmt"
// 1.publisher
type iPublish interface {
register(s iSub)
remove(s iSub)
notify()
}
type pub struct {
name string
inStock bool
subs []iSub
}
func NewPub(name string) *pub {
return &pub{name: name}
}
func (r *pub) register(s iSub) {
r.subs = append(r.subs, s)
}
func (r *pub) remove(s iSub) {
if len(r.subs) == 0 {
return
}
for i := 0; i < len(r.subs); i++ {
if r.subs[i] == s {
r.subs = append(r.subs[:i], r.subs[i+1:]...)
}
}
}
func (r *pub) notify() {
if len(r.subs) == 0 {
return
}
for i := 0; i < len(r.subs); i++ {
r.subs[i].update()
}
}
// 2.abstract subscribe
type iSub interface {
update()
}
// 3.concrete subscribe
type subSports struct {
name string
}
func (r *subSports) update() {
fmt.Printf("sub-sports %s received notify.\n", r.name)
}
type subFood struct {
name string
}
func (r *subFood) update() {
fmt.Printf("sub-food %s received notify.\n", r.name)
}
type subDigits struct {
name string
}
func (r *subDigits) update() {
fmt.Printf("sub-digits %s received notify.\n", r.name)
}
// 4.client
func main() {
p := NewPub("shopping")
p.register(&subSports{"Anta"})
p.register(&subFood{"Pepsi"})
p.register(&subSports{"Apple"})
p.notify()
}
参考文章:
标签:订阅,subs,iSub,优缺点,golang,notify,func,设计模式,name From: https://www.cnblogs.com/davis12/p/17469990.html