Observer model

The sample

Wechat public account, follow can receive push messages, cancel the follow will not receive

define

Defines a one-to-many dependency between objects. When one end object changes, all its dependencies are notified and automatically updated (the update method is called). The observer mode is also called: listener mode, publish/subscribe mode. Provides a loose-coupling design between objects interface – oriented programming, registration, callback mechanism

Design principles

Strive for loose coupling design between interacting objects

intentions

Defines a one-to-many dependency between objects. When one end object changes, all its dependencies are notified and updated automatically

Main problem solving

The problem of one object notifying other objects of state changes, with ease of use and low coupling in mind, ensuring a high degree of collaboration

When to use

When an object’s state changes, all dependencies are notified

The advantages and disadvantages

Advantages:

  1. The observer and the observed are abstractly coupled
  2. A trigger mechanism can be set up

Disadvantages:

  1. Notifying all observers takes time if there are many 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 does not know how the object of observation has changed, only that the object of observation has changed, right

Here’s the class diagram:Roles involved:

  1. Abstract Subject Role: Subject role keep all references to the observer in a gathered (such as the list collection), each theme can have any number of observers, abstract subject provides an interface that can add or remove the observer, the subject role also known as abstract (observables) observed, usually with an abstract class or interface implementation
  2. The Abstract Observer role: Defines an interface for all concrete observers to update themselves when notified by a topic. This interface is called the update interface. The abstract Observer role is usually implemented by an abstract class or interface
  3. ConcreteSubject Role: Stores state into a Concrete observer object, notifying all registered observers when the internal state of a specific topic changes. ConcreteSubject role, also called Concrete Observable role, is usually implemented by a subclass
  4. ConcreteObserver Role: Stores state that is consistent with the state of the topic, implementing the update interface required by the abstract observer role to harmonize its state with the state of the topic, usually implemented by a subclass

Subject:

public interface Subject {

    /** Add a new observer */
    void attach(Observer observer);

    /** Removes a registered observer */
    void detach(Observer observer);

    /** Notify all registered observers */
    void notifyObservers(a);
}
Copy the code

ConcreteSubject class:

public class ConcreteSubject implements Subject {

    private List<Observer> list = new ArrayList<>();

    @Override
    public void attach(Observer observer) {
        list.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        list.remove(observer);
    }

    @Override
    public void notifyObservers(a) {
        for(Observer o : list) { o.update(); }}}Copy the code

The Observer:

public interface Observer {

    /** The observer updates itself */
    void update(a);
}
Copy the code

ConcreteObserver class:

public class ConcreteObserver implements Observer {
    @Override
    public void update(a) {
        System.out.println("I am notified"); }}Copy the code

The story of the goddess and her pursuer

The goddess Cuihua is a flower in the village. There are many people pursuing it, such as Lao Wang who lives next door, Xiaoming who grew up together from childhood, and Tony teacher from the village barber shop. They are cuihua’s wechat friends and always pay attention to the dynamics of Cuihua. An example of an Observable class is as follows:

public interface Observable {

    /** Add observer */
    void addObserver(Observer observer);

    /** Remove observer */
    void removeObserver(Observer observer);

    /** Notify all observers */
    void notifyAllObservers(a);

}
Copy the code

Goddess Cuihua’s circle of friends:

public class GoddessPyq implements Observable {

    private List<Observer> list = new ArrayList<>();

    private String msg;

    @Override
    public void addObserver(Observer observer) {
        list.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        list.remove(observer);
    }

    public void pushMsg(String msg) {
        this.msg = msg;
        System.out.println("Post it on Moments:" + msg);
        notifyAllObservers();
    }

    @Override
    public void notifyAllObservers(a) {
        for(Observer o : list) { o.update(msg); }}}Copy the code

The Observer:

public interface Observer {

    / * * update * /
    void update(Object object);
}
Copy the code

Lao Wang, Xiao Ming, Tony’s circle of friends: always pay attention to whether Cuihua hair circle of friends

public class LaoWang implements Observer {
    @Override
    public void update(Object object) {
        System.out.println("LaoWang- Goddess next door:"+ object); }}Copy the code
public class XiaoMing implements Observer {
    @Override
    public void update(Object object) {
        System.out.println("XiaoMing- My dear goddess:"+ object); }}Copy the code
public class Tony implements Observer {
    @Override
    public void update(Object object) {
        System.out.println("Tony- beauty of frequent visitor:"+ object); }}Copy the code

Test class: goddess posted a circle of friends, Lao Wang, Xiao Ming, Tony can receive notification

public class Test {
    public static void main(String[] args) {
        GoddessPyq pyq = new GoddessPyq();
        pyq.addObserver(new LaoWang());
        pyq.addObserver(new Tony());
        pyq.addObserver(new XiaoMing());

        pyq.pushMsg("I was late for work today. I really want a ride.");
        System.out.println();
        pyq.pushMsg("Fancy a purse, but no money.");
        System.out.println();
        pyq.pushMsg("The computer broke down today."); }}Copy the code

Class diagram:

Implementation in Java

Java provides a common implementation of the Observer pattern: java.util. Observable, which extends the java.util.Observer interface

public class JDKObserverSample {

	public static void main(String[] args) {
		Observable subject1 = new Observable() {
			public synchronized void notifyObservers(Object data) {
				setChanged();
				super.notifyObservers(data); }}; subject1.addObserver(new Observer() {
			@Override
			public void update(Observable o, Object arg) {
				System.out.println("Observer 1 has been notified that it has been updated..."+ arg); }}); subject1.addObserver(new Observer() {
			@Override
			public void update(Observable o, Object arg) {
				System.out.println("Observer 2 has been notified that it has been updated..."+ arg); }}); subject1.notifyObservers("change1");
		subject1.notifyObservers("change2"); }}Copy the code

Observable is a class that doesn’t implement an interface, so the theme must inherit from it, which can be a problem if the theme wants to inherit from another class. Limit its reuse potential