The Observer Pattern is used when there is a one-to-many relationship between objects. For example, when an object is modified, its dependent objects are automatically notified. The observer model belongs to the behavioral model.

This means that when the observed changes, the observer automatically receives the data instead of actively notifying the observer every time the data changes.

The origin of the observer model

Now there is a demand for another major overhaul of Alipay, including the nearby rich function (hypothetically), and Alipay should promote this function to society, not only users, competitors, and government agencies.

But the speed of alipay revision is too fast, every time is to call the method of data change is too troublesome, so the observer mode (subscription publishing mode) and mail subscription is very similar.

Simple implementation of the observer pattern

Just set one observed object (Alipay) to inherit Observale and the other three observers to implement observers

Basic code for observer mode

Alipay

Public class ZhiFuBaoObservable extends Observable {/** * * @param string */ public void upgrade(string string){setChanged(); // notifyObservers that there is notifyObservers(string); }}Copy the code

observers

public class QunZhongObserver implements Observer { @Override public void update(Observable o, Object arg) {system.out.println (arg+"---- eat melon people say red envelope "); } } public class WeiXinObserver implements Observer { @Override public void update(Observable o, Object arg) {system.out.println (arg+"---- wechat means I will watch you install B"); } } public class YinLianObserver implements Observer { @Override public void update(Observable o, Object arg) {system.out.println (arg+"---- or Yang ma good, hungry not die I, xi xi xi "); }}Copy the code

The client

public class Client { public static void main(String[] args) { ZhiFuBaoObservable zhiFuBaoObservable = new ZhiFuBaoObservable(); QunZhongObserver qunZhongObserver = new QunZhongObserver(); WeiXinObserver weiXinObserver = new WeiXinObserver(); YinLianObserver yinLianObserver = new YinLianObserver(); zhiFuBaoObservable.addObserver(qunZhongObserver); zhiFuBaoObservable.addObserver(weiXinObserver); zhiFuBaoObservable.addObserver(yinLianObserver); ZhiFuBaoObservable. Upgrade (" 100th big changes, to join the rich around the function "); }}Copy the code

Custom observer mode

Source code analysis

Open the Observable class and add some comments:

Public Class Observable {// Set keys to change private Boolean changed = false; Private Vector obs; /** Construct an Observable with zero Observers. */ public Observable() { obs = new Vector<>(); Public synchronized void addObserver(Observer o) {if (o == null) throw new NullPointerException(); if (! obs.contains(o)) { obs.addElement(o); }} @param */ public synchronized void deleteObserver(Observer o) {obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } @param arg */ 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(); } 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

The observer class has only one method:

Public interface Observer {/** * call * @param o * @param arg */ void update(Observable, Object arg); }Copy the code

Quite simply, instead of implementing JDK classes at all, you can customize an observer pattern yourself

Custom Observer Mode

It is to combine Alipay and Observer and set up an internal interface as the parent interface of observers, which has advantages and disadvantages compared with the standard mode.

The realization of Alipay

Public class ZhiFuBao {private Boolean changed = false; Private ArrayList obs; /** * Construct an Observable with zero Observers. */ public ZhiFuBao() { obs = new ArrayList<>(); } public void publishMessage(String string){ setChanged(); notifyObservers(string); Public synchronized void addObserver(MyObserver o) {if (o == null) throw new NullPointerException(); if (! obs.contains(o)) { obs.add(o); }} @param o */ public synchronized void deleteObserver(MyObserver o) {obs.remove(o); } public void notifyObservers() { notifyObservers(null); } /** * notify all observers that data has changed ** @param arg */ 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--) ((MyObserver) arrLocal[i]).publishMessage(this, arg); } public synchronized void deleteObservers() { obs.removeAll(obs); } 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(); } public interface MyObserver {** * publishMessage */ void publishMessage(ZhiFuBao o, Object arg); }}Copy the code

The implementation of observers

public class QunZhong implements ZhiFuBao.MyObserver { @Override public void publishMessage(ZhiFuBao o, Object arg) {system.out.println (arg+"---- eat melon people say red envelope "); } } public class WeiXin implements ZhiFuBao.MyObserver { @Override public void publishMessage(ZhiFuBao o, Object arg) {system.out.println (arg+"---- wechat means I will watch you install B"); } } public class YinLian implements ZhiFuBao.MyObserver { @Override public void publishMessage(ZhiFuBao o, Object arg) {system.out.println (arg+"---- or Yang ma good, hungry not die I, xi xi xi "); }}Copy the code

Client-side implementation

ZhiFuBao zhiFuBao = new ZhiFuBao(); zhiFuBao.addObserver(new QunZhong()); zhiFuBao.addObserver(new WeiXin()); zhiFuBao.addObserver(new YinLian()); Zhifubao.publishmessage (" the 100th big revision, add around the rich function ");Copy the code

Custom decoupling is not as good as standard decoupling, but gives a better understanding of what each method does

The advantages and disadvantages

Advantages:

The observer and the observed are abstractly coupled.

2. Build a trigger mechanism.

Disadvantages:

1. If an observed object has many direct and indirect observers, it can take a long time to notify all observers.

2. If there is a cyclic dependency between the observer and the observing target, the observing target will trigger a cyclic call between them, possibly causing the system to crash.

3. The observer mode has no corresponding mechanism to let the observer know how the observed object has changed, but only to know that the observed object has changed.

See GitHub for more details