Observer pattern
When there is a one-to-many dependency between objects, when the state of the observed object changes, all the objects that observe it will be notified, which is the observer pattern.
basic idea
In observer mode, there are only two kinds of agents: the target object ( Subject
) and the observer ( Observer
).
In the observer pattern, the Subject object has methods to add, delete, and notify a series of Observers, etc., and the Observer object has update methods, etc. After the Subject object adds a series of Observer objects, the Subject object maintains the series of Observer objects, and the Subject object notifies the series of Observer objects to update when the relevant state changes.
advantage
- High coupling, usually used to achieve some responsive effects;
- The role is very clear, there is no event dispatch center as an intermediary, the target object
Subject
and the observerObserver
must implement the agreed member method; - The two parties are closely connected, and the target object is very active. It collects and maintains the observers by itself, and actively informs the observers to update when the state changes;
accomplish
// 目标对象
class Subject {
constructor() {
this.observers = []
}
add (observer) {
this.observers.push(observer)
}
notify() {
this.observers.map(observer => {
if (observer && typeof observer.update === 'function') {
observer.update()
}
})
}
remove(observer) {
const idx = this.observers.findIndex(itm => itm === observer)
if (idx !== -1) {
this.observers.splice(idx, 1)
}
}
}
// 观察者
class Observer {
constructor(name) {
this.name = name
}
update() {
console.log(`${this.name} updated`)
}
}
const subject = new Subject()
const o1 = new Observer('Nina')
const o2 = new Observer('Jack')
subject.add(o1)
subject.add(o2)
console.log('第一次通知:')
subject.notify()
subject.remove(o1)
console.log('删除 Nina 后,再次通知:')
subject.notify()
The output is:
publish-subscribe model
Based on an event (topic) channel, the object Subscriber
that wants to receive notifications subscribes to the topic through a custom event, and the object Publisher
of the activated event notifies each Subscriber
object that subscribes to the topic by publishing the topic event, which is the publish-subscribe mode.
There are three roles in publish-subscribe mode: publisher Publisher
, event dispatch center Event Channel
, subscriber Subscriber
.
Features
- In the publish-subscribe mode, there are no special constraints on the publisher
Publisher
and the subscriberSubscriber
, they publish and subscribe events through the interface provided by the event dispatch center, and they do not know who the other is; - Loosely coupled, high flexibility, often used as an event bus;
- It is easy to understand and can be compared to
dispatchEvent
andaddEventListener
in theDOM
event;
shortcoming
- When there are more and more types of events, it is difficult to maintain. It is necessary to consider the specification of event naming and prevent data flow confusion.
accomplish
class EventEmitter {
constructor() {
this.list = {}
if (!EventEmitter.instance) {
EventEmitter.instance = this
}
return EventEmitter.instance
}
on(name, fn) {
if (!this.list[name]) {
this.list[name] = []
}
this.list[name].push(fn)
}
emit(...rest) {
const name = ([].shift.call(rest))
const fns = this.list[name] || []
fns.forEach((fn) => {
fn.apply(this, rest)
})
}
off(name) {
this.list[name] = []
}
clean() {
this.list = {}
}
}
const e1 = new EventEmitter()
e1.on('go', (name) => console.log(`${name} 走了`))
e1.on('come', (name) => console.log(`${name} 来了`))
e1.emit('go', 'Nina')
e1.emit('go', 'Jack')
e1.emit('come', 'Bill')
difference between the two
concept and implementation
- Conceptually, there is no difference between the two. They both resolve the decoupling between objects and trigger events at a certain point in time. Subscribers listening to this event can perform corresponding operations.
- There are differences in implementation. The observer mode maintains the subscribers who subscribe to the events through the publisher itself, and some subsequent column operations must be completed by the publisher. The publish-subscribe model is that there will be an event bus between the subscriber and the publisher, and operations must be completed through the event bus.
coupling
- The Observer pattern is target- and observer-oriented programming for coupling targets and observers. There is still coupling between the observer and the observed, and the observed still knows the observer;
- The publish-subscribe model is programmed for the dispatch center to decouple publishers and subscribers. Publishers and subscribers do not need to know the existence of each other, they communicate through the message broker , and the decoupling is more thorough;
relation
- The observer and the observed in the observer mode are like the relationship between merchant-customer . When the product is updated, the merchant will directly notify the subscribed customers.
- Publishers and subscribers in the publish-subscribe model are like the relationship between merchant-APP-customer . Customers (subscribers) subscribe to product notifications on the APP. When the products are updated, the merchants (publishers) notify the subscribed through the APP. Customers (Subscribers).
From a usage perspective
- Observer mode, mostly used inside a single application;
- The publish-subscribe model is more of a cross-application pattern, such as message middleware;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。