Some say that these two patterns are actually the same pattern. That’s half right, half wrong. There are similarities, but not exactly the same. Let’s start with a diagram that illustrates some of the flow differences between the Observer and publish-subscribe modes:
To elaborate the models of both:
-
In Observer mode, the Observer directly subscribes to the Subject, and when the Subject is activated, it fires events in the Observer.
-
In the publish and subscribe mode, Subscriber listens for the events in the Event Bus. When the events in the Event Bus are triggered, Subscriber will perform the corresponding operations. It is important to note that events in the event bus are triggered by the Publisher and notification event bus.
Observer model
As shown above, since publish/subscribe is something more than the observer model, let’s look at the observer model first.
Observer pattern: Defines a one-to-many dependency between objects
In simple terms, object A relies on A certain state change of object B to perform some logic, so A needs to observe A certain state of B, B will notify A when this state changes, and can give data describing this state to A
Here’s an example:
Suppose you are a poor student, your deskmate is an excellent student, today is going to take an exam, the paper hair down, you almost a question will not do, so you say to the deskmate: you finished to me copy, your deskmate finished, take your elbow to poke you once, the paper to your side move.
You are the observer, your deskmate is the observed, you observe the state is your deskmate finished, your deskmate’s paper is the data you want, when this state happens, you have to deal with the logic is copying answers.
If you’ve ever copied an assignment, you know you can’t just stare at your desk mate or ask him if he’s done it? In A program, if object A keeps trying to get some state of B to see if it changes, it’s not observer mode
What is a one-to-many dependency?
Your deskmate is a student with excellent results, and you are the same as you are a student with poor results. You have to copy his, or all fail. That’s it.
In an application, a button is clicked and the application opens a page. The so-called listening for the button click event is an observer mode
Lu code
Constructor (){this.arr = [] this. State = "happy..." } attach(unit){this.arr.push(unit)} // Change state setState(newState){this.state = newState ForEach (unit=>unit.update(newState))}} class constructor {constructor(name){this.name = name} Update (newState){console.log(this.name," status: ",newState); update(newState){console.log(this.name," status: ",newState); }} let s = new Subject(" baby ") let o1 = new Observer(" I ") let O2 = new Observer(" you ") s.atach (o1) s.atach (o2) console.log(s.state); / / happy... S. setstate (" not happy..." ); // My status: unhappy... Your status: Unhappy... console.log(s.state); // Not happy...Copy the code
Publish and subscribe model
In the publish-subscribe model, the sender of a message, called publishers, is not sent directly to a specific recipient, called a subscriber.
This means that publishers and subscribers are unaware of each other’s existence. You need a third-party component, called middleware, that connects subscribers and publishers.
Here’s an example:
You take a fancy to a computer on Taobao, and then you find a purchasing agent, you tell him that if you find this computer to buy you, there are many channels in the purchasing way, after the arrival of the computer these channels will tell the purchasing agent, the arrival of the computer, and then buy down to you
This is the publish subscribe model
What about the observer model?
You took a fancy to a computer on taobao, but did not have goods, so you give inn said arrival told you, inn said good, arrival told you.
This is the observer model
In an application, for example, an application can distinguish between the logged in and unlogged UI. Many different pages can implement the logon logic. After a successful login, all the currently opened pages need to update the UI. In this case, a publish/subscribe model can be used. After a successful login on one page, a successful login event can be published, and middleware will distribute this event to other pages to update the UI. Note: other pages only care about the login status change, not the specific page of the user login
Lu code:
Let e = {arr: [], on (fn) {this. Arr. Push (fn)}, emit () {this. Arr. ForEach (fn = > fn ())}} e.on (() = > {the console. The log (" ha ha 1 "); }) e.on(()=>{console.log(" ha ha 2"); }) // tune once print once e.mit () // haha1 haha2 e.mit () // haha1 haha2Copy the code
The difference between:
The difference between these two modes can simply boil down to observed states or events.
In observer mode:
- Status publishers maintain a list of observers, explicitly knowing which observers exist and notifying them of state changes directly
- The observer of the state also knows exactly which object the state he is observing is describing
- You even need this mutual knowing relationship to handle logic (for example, you need to know exactly which button is clicked to handle the corresponding logic)
Publish and subscribe model:
- Event publishers only publish events, not care who gets the event, and usually send the event to a middleware that distributes the event
- Event subscribers care only about the event itself, not who published it, and typically de-register an event in middleware to observe it
- The list of subscribers corresponding to the event category is maintained in the middleware, and subscribers are notified in the corresponding list when an event is received
Application scenarios
Judge according to the following principles:
Whether the state is being observed (clearly knowing the state source)
If both the observed and the observer clearly know each other, then observer, otherwise publish and subscribe
One-to-one or one-to-many relationships
There is only one publisher for this event or state. Either can be used. Refer to # 1 again
Many-to-many relationships
First, the many-to-many relationship is basically a guarantee of passing events, not states, because different objects should not publish the same state, so don’t hesitate to publish/subscribe