基础知识请参考往期博文
发布订阅模式解释
https://blog.csdn.net/liuyukuan/article/details/83720912讲故事,学(AHK)设计模式—观察者模式
https://blog.csdn.net/liuyukuan/article/details/84428817
直接上AutoHotkey V2 实现的“发布订阅模式”示例
;发布订阅模式解释
;https://blog.csdn.net/liuyukuan/article/details/83720912
; 定义一个全局变量来存储订阅者列表
global subscribers := Map()
; 订阅函数,用于添加订阅者
Subscribe(eventName, callback) {
if (!subscribers.Has(eventName)) {
subscribers[eventName] := []
}
subscribers[eventName].Push(callback)
}
; 取消订阅函数,用于移除订阅者
Unsubscribe(eventName, callback) {
if (subscribers.Has(eventName) && IsObject(subscribers[eventName])) {
for idx, func in subscribers[eventName] {
; 注意:直接比较函数对象可能不可靠,但在此简化示例中我们仍这样做
if (func == callback) {
subscribers[eventName].RemoveAt(idx)
Return
}
}
}
}
; 发布函数,用于触发事件并调用所有订阅者的回调函数
Publish(eventName, args) {
if (subscribers.Has(eventName) && IsObject(subscribers[eventName])) {
for callback in subscribers[eventName] {
; 直接调用回调函数并传递参数
callback(args)
}
}
}
; 示例订阅者回调函数
OnMessageReceived(message:="") {
MsgBox("Received message: " . message)
}
; 示例使用
Subscribe("messageReceived", OnMessageReceived)
Publish("messageReceived", "Hello from Publisher!")
; 取消订阅示例
Unsubscribe("messageReceived", OnMessageReceived)
Publish("messageReceived", "This message should not be received.")
观察者模式和发布订阅模式的区别
观察者模式:某公司给自己员工发月饼发粽子,是由公司的行政部门发送的,这件事不适合交给第三方,原因是“公司”和“员工”是一个整体 。
发布-订阅模式:某公司要给其他人发各种快递,因为“公司”和“其他人”是独立的,其唯一的桥梁是“快递”,所以这件事适合交给第三方快递公司解决。
上述过程中,如果公司自己去管理快递的配送,那公司就会变成一个快递公司,业务繁杂难以管理,影响公司自身的主营业务,因此使用何种模式需要考虑什么情况两者是需要耦合的。
在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。