The observer pattern, also known as publish-subscribe or “listener pattern”, is one of the behavioral patterns in the design pattern. WebFlux, which has become popular in recent years, is one of the applications of the observer pattern.

The core idea of the Observer mode is that when the state of an Observable changes (an object is modified/reacts/publishes a message, etc.), it notifies the Observer listening to the object one by one.

The behavior of the observer observing the observed is called subscribe or register, the observed notifies the observer, and the response of the observer is called update.

For example: WHEN I watch TV, I am the observer, and TV is the observed. When I watch TV, this behavior is called subscription. When there is a traditional kung fu of Teacher Ma on TV, I immediately smash the TV, and this behavior is response. This is the simple one-to-one observer model.

The reality is that when a program comes out, there must be more than one person around the world watching it, so an observed can have many observers, and the observer mode mainly deals with a one-to-many dependency relationship.

Observer Pattern: Defines a one-to-many dependency between objects. When an object’s state changes, all dependent objects are notified and automatically updated.

Now let’s define an observer interface

public interface Observer {
    void update(String event);
}
Copy the code

The update method is used to respond to events

An observed parent

public class Observable { private List<Observer> observers = new ArrayList<>(); public void addObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { observers.remove(observer); Public void notifyObservers(String event) {for (Observer Observer: observers) { observer.update(event); }}}Copy the code

They maintain a list of observers with a list, addObserver adds observers, removeObserver removes observers, and notifyObservers of updates, one by one

Now define a TV program class that inherits the observed parent class

Public class Television extends Observable{public void play(String event) {system.out.println (" TV is playing "+ event); notifyObservers(event); }}Copy the code

The Play method is a tV-program-like behavior that notifies all subscribers, the viewers of the TV, when executed

Define a human observer to implement the observer interface

Public class ManObserver implements Observer{@override public void update(String event) {system.out.println (" New TV series: "+ event); }}Copy the code

Overrides the observer response method to print a piece of data

Test method:

public static void main(String[] args) throws Exception { Television television = new Television(); Observer zhangSan = new ManObserver(); Observer liSi = new ManObserver(); Observer wanWu = new ManObserver(); television.addObserver(zhangSan); television.addObserver(liSi); television.addObserver(wanWu); Television. Play (" The lure of going back to the village "); }Copy the code

Create a new TV object and add three human observers: Joe, Joe, And Joe, who are lying in bed watching TV.

Print the following:

TV is playing back to the temptation of the village to receive the message, there is a new TV play online: the temptation of the village to receive the message, there is a new TV play online: the temptation of the villageCopy the code

All three received the message

When a subscriber no longer needs to observe, removeObserver () is used to remove the observer object

The observer pattern is also used in SpringFramework design, which is the event mechanism and listener. Listeners act as subscribers and listen for specific events; Event sources act as observed topics for publishing events; The IOC container itself is also an event broadcaster, which can be understood as an observer.

Similarly, the Java source code already has an observer and observed implementation, so we don’t need to define it ourselves:

Java. Util. The Observer class:

public interface Observer {
    void update(Observable o, Object arg);
}
Copy the code

The input parameter of the response method is changed to the broader Object type, and the observed Object is also passed in

Java. Util. Observables class:

public class Observable { private boolean changed = false; private Vector<Observer> obs; public Observable() { obs = new Vector<>(); } public synchronized void addObserver(java.util.Observer o) { if (o == null) throw new NullPointerException(); if (! obs.contains(o)) { obs.addElement(o); } } public synchronized void deleteObserver(java.util.Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (! hasChanged()) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length - 1; i >= 0; i--) ((Observer) arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } public synchronized int countObservers() { return obs.size(); }}Copy the code

Note the changed methods, and notifyObservers, that they notify subscribers only when setChanged() is called so that changed is true, and that observers do not maintain a list of subscribers as a list, but rather as a Vector, Synchronized keyword is added to ensure thread safety.