GoLang设计模式13 - 观察者模式
观察者模式是一种行为型设计模式。这种模式允许一个实例(可以称为目标对象)发布各种事件(event)给其他实例(观察者)。这些观察者会对目标对象进行订阅,这样每当目标对象发生变化时,观察者就会收到事件(event)通知。
来看个例子:在电商网站经常会有各种商品脱销,假如有顾客已经在关注这些商品,这些商品的脱销就会对他们产生不好的体验。如果顾客还想买这些商品,那么通常有如下解决方案:
- 顾客以一定的频率检查这些商品是否在售
- 电商平台将所有的上架的商品信息定期推送给用户
- 顾客只订阅他所关注的特定商品的信息,当这些商品再次上架时他们会收到通知;多个顾客可以订阅同一个商品的信息
选项3是最为可行的一种方案。这也正是观察者模式所能做到的事情。观察者模式的核心组件为:
- Subject : 目标对象,是有变化发生时就会发布相关事件的实例
- Observer : 观察者,订阅目标对象的信息,会收到一些特定事件的通知
通常,Subject和Observer会被定义为接口,真正使用的是它们二者的具体实现。
UML类图如下:
下面是一个示例代码:
observer.go:
1
2
3
4
|
type observer interface { update(string) getID() string } |
subject.go:
1
2
3
4
5
|
type subject interface { register(Observer observer) deregister(Observer observer) notifyAll() } |
item.go:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
import "fmt" type item struct { observerList []observer name string inStock bool } func newItem(name string) *item { return &item{ name: name, } } func (i *item) updateAvailability() { fmt.Printf( "Item %s is now in stock\n" , i.name) i.inStock = true i.notifyAll() } func (i *item) register(o observer) { i.observerList = append(i.observerList, o) } func (i *item) deregister(o observer) { i.observerList = removeFromSlice(i.observerList, o) } func (i *item) notifyAll() { for _, observer := range i.observerList { observer.update(i.name) } } func removeFromSlice(observerList []observer, observerToRemove observer) []observer { observerListLength := len(observerList) for i, observer := range observerList { if observerToRemove.getID() == observer.getID() { observerList[observerListLength-1], observerList[i] = observerList[i], observerList[observerListLength-1] return observerList[:observerListLength-1] } } return observerList } |
customer.go:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import "fmt" type customer struct { id string } func (c *customer) update(itemName string) { fmt.Printf( "Sending email to customer %s for item %s\n" , c.id, itemName) } func (c *customer) getID() string { return c.id } |
在上面的代码中item是subject的实现,customer是observer实现。
看下场景类main.go:
1
2
3
4
5
6
7
8
|
func main() { shirtItem := newItem( "GoLang Design Patterns" ) observerFirst := &customer{id: "robin@zhyea.com" } observerSecond := &customer{id: "golang@zhyea.com" } shirtItem.register(observerFirst) shirtItem.register(observerSecond) shirtItem.updateAvailability() } |
执行后输出内容为:
1
2
3
|
Item GoLang Design Patterns is now in stock Sending email to customer robin@zhyea.com for item GoLang Design Patterns Sending email to customer golang@zhyea.com for item GoLang Design Patterns |
代码已上传至GitHub: zhyea / go-patterns / observer-pattern
END!
仅是学习笔记,难免出错,望不吝指点
转 https://www.cnblogs.com/amunote/p/15520742.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)