Mode 15: Observer Mode and JDK's Inborn Observer Mode

[Introduction]

Take Vs2019 for example, when you click Run Program, the key will change, and if you add an error box, it won't change anywhere else. This is typical Observer mode.

1. Observer Mode

Observer Pattern: Defines a one-to-many dependency between objects that is notified and automatically updated whenever an object's state changes. The observer mode is also known as the Publish/Subscribe mode, the Model/View mode, the Source/Listener mode, or the Dependents mode. The observer mode is an object behavior mode.

Many times, we compare the observer mode with the publish-subscribe mode.

Simply put, the publishing and subscription mode belongs to the observer mode in a broad sense. On the basis of the Subject and Observer of the observer mode, Event Channel is introduced as an intermediary to further decouple. As shown in the following figure:

UML Class Diagram Design:

Subject: Notifier abstract class responsible for adding and deleting notified objects and notification information. It is associated with the observer.
ConcreteSubject: Specific notifier, inherited notifier Abstract class, with specific notification information.
Observer: An observer abstract class that has a response to notification information.
ConcreteObserver: Specific observers rely more on abstraction.

Abstract observer

public abstract class Observer {
    public abstract void update();
}

Specific observer

public class ConcreteObserver extends Observer {
    private String name;
    private String observerState;
    private ConcreteSubject subject;

    public ConcreteObserver(ConcreteSubject subject, String name) {
        this.subject = subject;
        this.name = name;
    }

    public void setObserverState(String observerState) {
        this.observerState = observerState;
    }

    public ConcreteSubject getSubject() {
        return subject;
    }

    @Override
    public void update() {
        observerState = subject.getState();
        System.out.println("Observer" + name + "The new state is" + observerState);
    }
}

Abstract Notifier

public abstract class Subject {
    private List<Observer> observers=new ArrayList<>();
    //Increase Observer
    public void increase(Observer observer){
        observers.add(observer);
    }
    //Remove Observer
    public void delete(Observer observer){
        observers.remove(observer);
    }
    //notice
    public void Notify(){
        for(Observer observer:observers) {
            observer.update();
        }
    }
}

Specific Notifier

public class ConcreteSubject extends Subject{
    private String state;
    //Observer state

    public void setState(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }
}

Client

public class Client {
    public static void main(String[] args) {
        ConcreteSubject subject=new ConcreteSubject();
        subject.increase(new ConcreteObserver(subject,"X"));
        subject.increase(new ConcreteObserver(subject,"Y"));
        subject.increase(new ConcreteObserver(subject,"Z"));
        subject.setState("123");
        subject.Notify();
    }
}

2. Instance Application

Example: The company's front desk, once the boss appears, informs lazy employees.

Subject class

/**
 * Notifier Interface
 */
interface Subject {
    void increase(Observer observer);
    void delete(Observer observer);
    void Notify();
    String state = null;
    void setState(String state);
    String getState();
}

Boss Boss

public class Boss implements Subject{
    //Simultaneous List
    private List<Observer> observers=new ArrayList<>();
    private String action;
    //increase
    @Override
    public void increase(Observer observer) {
        observers.add(observer);
    }
    //reduce
    @Override
    public void delete(Observer observer) {
        observers.remove(observer);
    }
    //notice
    @Override
    public void Notify() {
        for(Observer observer:observers)
            observer.update();
    }
    //Boss status
    @Override
    public String getState() {
        return action;
    }

    @Override
    public void setState(String state) {
        action=state;
    }
}

Secretary class

//Foreground class
public class Secretary implements Subject{
    //Simultaneous List
    private List<Observer> observers=new ArrayList<>();
    private String action;
    //increase
    @Override
    public void increase(Observer observer) {
        observers.add(observer);
    }
    //reduce
    @Override
    public void delete(Observer observer) {
        observers.remove(observer);
    }
    //notice
    @Override
    public void Notify() {
        for(Observer observer:observers)
            observer.update();
    }
    //Boss status
    @Override
    public String getState() {
        return action;
    }

    @Override
    public void setState(String state) {
        action=state;
    }
}

Observer class

public abstract class Observer {
    private String name;
    private Subject subject;

    public Observer(String name, Subject subject) {
        this.name = name;
        this.subject = subject;
    }

    public String getName() {
        return name;
    }

    public Subject getSubject() {
        return subject;
    }

    public abstract void update();
}

Specific observer

/**
 * Colleagues Watching Stocks
 */
public class StockObserver extends Observer{
    public StockObserver(String name,Subject subject){
        super(name, subject);
    }

    @Override
    public void update() {
        System.out.println(getSubject().getState()+" "+getName()+": "+"Close the stock and keep working!");
    }
}
/**
 * Watch your colleagues in the NBA
 */
public class NBAObserver extends Observer{
    public NBAObserver(String name,Subject subject){
        super(name, subject);
    }

    @Override
    public void update() {
        System.out.println("[Boss):"+getSubject().getState()+" "+getName()+"Close NBA Live, keep working!");
    }
}

Client

public class Client {
    public static void main(String[] args) {
        Boss xiaoming=new Boss();
        StockObserver colleague1=new StockObserver("petty thief",xiaoming);
        NBAObserver colleague2=new NBAObserver("Xiao Hu",xiaoming);
        xiaoming.increase(colleague1);
        xiaoming.increase(colleague2);
        xiaoming.delete(colleague1);
        xiaoming.setState("Let me see if you're doing a good job! ");
        xiaoming.Notify();
    }
}

3. Summary of Modes

1. Advantages of the observer mode

  • The observer mode separates the presentation layer from the data logical layer, defines a stable messaging update delivery mechanism, and abstracts the update interface so that different representation layers can be used as specific observer roles.
  • The observer mode creates an abstract coupling between the observer and the observer. (
  • The observer mode supports broadcast communication.
  • The observer mode meets the requirements of the Open and Close Principle.

2. Disadvantages of the observer model

  • If there are many direct and indirect observers for an observer, it takes a lot of time to notify all the observers.
  • If there is a circular dependency between the observer and the observer target, the observer target triggers a circular call between them, which may cause the system to crash.
  • There is no mechanism for observer mode to let the observer know how the observed object has changed, only that the observed object has changed.

3. Scenarios for the observer mode

  • An abstract model has two aspects, one of which depends on the other. These aspects are encapsulated in separate objects so that they can be changed and reused independently of each other.
  • Changing an object causes one or more other objects to change, without knowing how many objects will change, which reduces the coupling between objects.
  • An object must notify other objects without knowing who they are.
  • A trigger chain needs to be created in the system. The behavior of A object will affect B object, and the behavior of B object will affect C object.... You can use the observer mode to create a chain trigger mechanism.

4. Application of Observer Mode

1. JDK's inherent observer model:

Implementation Requirements

Java. The Observable class and Observer interface are provided in the util package, which requires that the observer inherit the Observable class and the observer implement the Observer interface

Give an example

public class HuaWeiP30 extends Observable {
    //Mobile Price
    private double price;

    public HuaWeiP30(double price) {
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    public void updatePrice(double price) {
        if (price != this.price) {
            this.setChanged();
            if (price < this.price) {
                //Notify observers
                this.price = price;
                this.notifyObservers();
            } else
                this.price = price;
        }

    }

    @Override
    public String toString() {
        return "Current Huawei Mobile Phone P30 Price:" + price + "element";
    }
}
public class HuaWeiFans implements Observer {
    private String name;

    public HuaWeiFans(String name) {
        this.name = name;
    }

    /**
     *
     * @param o:Observed Object
     * @param arg:Parameters passed to the observer
     */
    @Override
    public void update(Observable o, Object arg) {
        updatePrice(o);
    }

    private void updatePrice(Observable o) {
        HuaWeiP30 p30= (HuaWeiP30) o;
        System.out.println("Fan Name" + name + "Discover Huawei p30 The price has been reduced. The new price is:" + p30.getPrice() + "Yuan, start buying.");
    }
}

Write test classes

public class Client {
    public static void main(String[] args) {
        HuaWeiP30 p = new HuaWeiP30(5000);
        HuaWeiFans A = new HuaWeiFans("A");
        HuaWeiFans B = new HuaWeiFans("B");
        HuaWeiFans C = new HuaWeiFans("C");
        HuaWeiFans D = new HuaWeiFans("D");

        p.addObserver(A);
        p.addObserver(B);
        p.addObserver(C);
        System.out.println(p);
        p.updatePrice(3000);
        System.out.println(p);
    }
}

 

2. Spring Event Mechanism

Spring implements its own event mechanism based on the observer model, which consists of three parts:

  • Event ApplicationEvent: Implement custom events by inheriting it. In addition, the event source can be obtained through its source property, and the timestamp property can get the time of occurrence.

  • Application Event Publisher: This enables event publishing.

  • Event listener ApplicationListener: Implements it to listen for events of a specified type.

JDK also has a built-in implementation of event mechanisms on which Spring extends due to their versatility. Therefore, ApplicationEvent inherits from java.util.EventObject, ApplicationListener inherits from java.util.EventListener.

If your article is useful to you, support it three times!!!

Keywords: Java JDK Design Pattern

Added by Fuzzy Wobble on Mon, 07 Feb 2022 19:41:25 +0200