观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个“观察”该对象的其他对象。
解决什么问题?
如果需要对感兴趣的对象进行通知,不感兴趣的对象不需要通知,使用观察者模式很适合。通过维护一个订阅者列表,向特定的对象发送通知。
实现步骤:
- 定义
inotify接口 订阅者实现inotify接口和相关函数发布者提供订阅、通知等相关接口
优势:
- 开闭原则。 你无需修改发布者代码就能引入新的订阅者类 。
- 你可以在运行时建立对象之间的联系。
劣势:
- 订阅者的通知顺序是随机的。
下面是实现代码:
package main
import "fmt"
import "time"
type notify interface {
update()
}
type subscriber struct {
registerId int
ch chan struct{}
}
func newSubscriber() *subscriber {
return &subscriber{
registerId: -1,
ch: make(chan struct{}, 1),
}
}
func (s *subscriber) setRegisterId(id int) {
s.registerId = id
}
func (s *subscriber) update() {
s.ch <- struct{}{}
}
func (s *subscriber) waitNoitify() {
<-s.ch
fmt.Printf("subscriber[%d] do something\n", s.registerId)
}
type publisher struct {
registerId int
subscriberList map[int]notify
}
func newPublisher() *publisher {
return &publisher{
registerId: 0,
subscriberList: map[int]notify{},
}
}
func (p *publisher) subscribe(s notify) int {
id := p.registerId + 1
p.registerId = id
p.subscriberList[id] = s
fmt.Printf("subscriber[%d] subscribe successfully!!!\n", id)
return id
}
func (p *publisher) unSubscribe(registerId int) {
delete(p.subscriberList, registerId)
fmt.Printf("subscriber[%d] unsubscribe successfully!!!\n", registerId)
}
func (p *publisher) notifySubscribers() {
for k, v := range p.subscriberList {
fmt.Printf("publisher inotify subscriber[%d]\n", k)
v.update()
}
}
func main() {
p := newPublisher()
s1 := newSubscriber()
s2 := newSubscriber()
id := p.subscribe(s1)
s1.setRegisterId(id)
id = p.subscribe(s2)
s2.setRegisterId(id)
go s1.waitNoitify()
go s2.waitNoitify()
p.unSubscribe(s1.registerId)
p.notifySubscribers()
time.Sleep(time.Second)
}
输出:
subscriber[1] subscribe successfully!!!
subscriber[2] subscribe successfully!!!
subscriber[1] unsubscribe successfully!!!
publisher inotify subscriber[2]
subscriber[2] do something