Foreword: Recently, in learning RxJava, RxJava has been extended on the basis of observer mode. This article takes you to understand the observer mode.
What is the Observer Model
The observer pattern is the object's behavior pattern, also known as Publish/Subscribe, Model/View, Source/Listener or Dependents.
When there is a one-to-many relationship between objects, the observer pattern is suitable. When an object is modified, its dependent object is automatically notified. The observer model belongs to the behavioral model.
For example, after the successful payment of the order, it may reduce the inventory of goods, calculate the membership points, notify the logistics delivery and so on.
Some concepts in the observer model
- Observable Observed
- Observer Observer
If you abstract the example just given into an observer pattern, it should be like this.
Java API
Java provides us with two API s, Observable and Observer, which can be used to extend the implementation of the observer pattern.
The observer interface is simple. When the observer changes, all observers are notified through the update method.
public interface Observer { void update(Observable o, Object arg); }
Observed code, a little more, but it is not complicated. JDK provides us with a thread-safe observer model
public class Observable { private boolean changed = false; // Collection of observers private Vector<Observer> obs; public Observable() { obs = new Vector<>(); } // Observer subscription public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } // Observers cancel subscriptions public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } // Notify all observers public void notifyObservers() { notifyObservers(null); } // Notify all observers public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed) 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(); } // Changes in the observee 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(); } }
Realization
Xiao Li Zi: Push it to all subscribers when publishing articles by public number
/** * Public Number * (Observed) */ class OfficialAccount extends Observable { // Publish articles public void publishArticle(String article) { setChanged(); notifyObservers(article); } }
/** * user * (Observer) */ class User implements Observer { private String username; User(String username) { this.username = username; } @Override public void update(Observable o, Object arg) { System.out.println("Users:" + username + ", Received subscription articles:" + arg); } }
public class Run { public static void main(String[] args) { OfficialAccount officialAccount = new OfficialAccount(); User ytw = new User("ytw"); User hmj = new User("hmj"); officialAccount.addObserver(ytw); officialAccount.addObserver(hmj); officialAccount.publishArticle("SpringBoot"); officialAccount.publishArticle("Java Understanding the Observer Model"); } }
A little understanding
When learning the observer model, it always feels very similar to producer and consumer, both of which are well decoupled. The above observer model, if there are many subscribers, is inefficient (because it is synchronous). Individual understanding of the producer-consumer model is a variant of the observer model. Producer-consumer mode adds buffer queues, which can achieve good asynchronous message throughput.