JavaScript观察者模式(publish/subscribe)原理与实现方法
观察者模式,也叫发布订阅模式,是一种对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。这种设计模式在前端开发中应用广泛,比如实现事件监听、多模块协同、组件间通信等。
原理
观察者模式包含如下角色:
- 主题(Subject):在其中定义一个添加、删除和通知观察者对象的接口。
- 观察者(Observer):定义一个叫做update()的接口,当接收到主题发来的通知时被调用。
- 具体主题(ConcreteSubject):将有关状态存到具体观察者对象;在有状态变化时,给每个观察者发出通知。
- 具体观察者(ConcreteObserver):实现观察者接口,保存有关主题的状态,具体主题对象发生变化时更新自己的状态。
具体实现过程:
- 创建主题类,包含添加、删除观察者、通知观察者的方法。
class Subject {
constructor() {
this.observers = new Set() // Set保证不重复
}
// 添加观察者
addObserver(observer) {
this.observers.add(observer)
}
// 删除观察者
removeObserver(observer) {
this.observers.delete(observer)
}
// 通知观察者
notify(data) {
for (const observer of this.observers) {
observer.update(data)
}
}
}
- 创建观察者类,包含update()方法。
class Observer {
update(data) {
// 处理业务逻辑
}
}
- 创建具体主题类,继承自主题类,实现具体状态变化时通知观察者的方法。
class ConcreteSubject extends Subject {
constructor() {
super()
this.state = '' // 保存状态
}
// 具体状态变化时通知观察者
setState(state) {
if (this.state !== state) {
this.state = state
this.notify(state)
}
}
}
- 创建具体观察者类,继承自观察者类,实现update()方法。
class ConcreteObserver extends Observer {
constructor() {
super()
this.state = ''
}
update(data) {
this.state = data
// 处理业务逻辑
}
}
- 使用时,先创建具体主题对象,再创建具体观察者对象并添加到主题的观察者列表,通过调用具体主题对象的setState()方法来触发通知。
const subject = new ConcreteSubject()
const observer1 = new ConcreteObserver()
subject.addObserver(observer1)
const observer2 = new ConcreteObserver()
subject.addObserver(observer2)
subject.setState('state1') // 通知所有观察者更新状态
实现方法
除了上述的基本实现外,观察者模式还有一些常见的变种实现方法,如:使用事件监听机制实现、使用回调函数实现等。
使用事件监听机制实现
使用DOM事件监听机制实现观察者模式,代码如下:
class Subject {
constructor() {
this.handlers = {}
this.id = 0
}
// 添加订阅者
addEventListener(type, handler) {
if (!this.handlers[type]) {
this.handlers[type] = []
}
this.handlers[type].push({ id: ++this.id, handler })
}
// 移除订阅者
removeEventListener(type, id) {
if (this.handlers[type]) {
this.handlers[type] = this.handlers[type].filter(
item => item.id !== id
)
}
}
// 发布消息
dispatchEvent(type, data) {
if (this.handlers[type]) {
this.handlers[type].forEach(item => {
item.handler(data)
})
}
}
}
使用时,将具体观察者对象的业务逻辑封装成回调函数,然后作为订阅者加入到主题对象的事件监听列表中。
const subject = new Subject()
function callback1(data) {
// 处理业务逻辑
}
function callback2(data) {
// 处理业务逻辑
}
subject.addEventListener('change', callback1)
const id = subject.id // 记录订阅者ID
subject.addEventListener('change', callback2)
subject.dispatchEvent('change', 'data') // 发布消息
subject.removeEventListener('change', id) // 移除订阅者
使用回调函数实现
使用回调函数实现观察者模式,代码如下:
class Subject {
constructor() {
this.callbacks = []
}
// 添加订阅者
subscribe(callback) {
this.callbacks.push(callback)
}
// 移除订阅者
unsubscribe(callback) {
this.callbacks.splice(this.callbacks.indexOf(callback), 1)
}
// 发布消息
notify(data) {
this.callbacks.forEach(callback => {
callback(data)
})
}
}
与上一种实现方式不同的是,具体观察者对象的业务逻辑直接封装在回调函数中,然后作为订阅者加入到主题对象的回调函数列表中。
const subject = new Subject()
function callback1(data) {
// 处理业务逻辑
}
function callback2(data) {
// 处理业务逻辑
}
subject.subscribe(callback1)
subject.subscribe(callback2)
subject.notify('data') // 发布消息
subject.unsubscribe(callback2) // 移除订阅者
以上就是JavaScript观察者模式(publish/subscribe)的原理与实现方法的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript观察者模式(publish/subscribe)原理与实现方法 - Python技术站