Observer mode of 23 design modes

Observer mode of 23 design modes

reference material

Please correct any mistakes and omissions below

1, Introduction

definition

It refers to the one to many dependency between multiple objects. When the state of an object changes, all objects that depend on it will be notified and updated automatically. (all observers will be notified when the content of the observed changes)

characteristic

  • The observer model is a behavioral model

General class diagram

Important roles of observer mode:

  • Subject

    Observer role

    It provides a collection for saving observer objects, which can dynamically add and delete observers. Used to manage and inform observers.

  • ConcreteSubject

    Specific observer role

    Define your own business logic and implement the abstract methods in the abstract observed. When the internal state of the specific observed changes, it will notify all registered observer objects.

  • Observer

    Abstract observer role

    It is an abstract class or interface that contains an abstract method of update, which is called when the message from the observer is received.

  • ConcreteObserver

    Specific observer role

    Implement the abstract methods defined in the abstract observer, and each observer has its own processing logic.

advantage

  • It reduces the coupling relationship between the observed and the observer, which is an abstract coupling relationship. In this design, it is very easy to expand whether the observer or the observed is added.
  • A trigger mechanism is established between the observed and the observer. The observed sets the trigger conditions and notifies all observers once triggered.

shortcoming

  • The dependency between the observed and the observer has not been completely removed, and there may be circular references, that is, the observer may also be the observed.

  • When there are many observers, the notification of the press conference takes a lot of time, which affects the efficiency of the program.

Application scenario

  • There is a one to many relationship between objects. The change of the state of one object will affect other objects.
  • When an abstract model has two aspects, one of which depends on the other, they can be encapsulated in independent objects so that they can be changed and reused independently.
  • Cross system message exchange scenarios, such as the processing mechanism of message queue.

2, Observer mode

Requirements:

Now there is a stock. Investors can set the reminder when the stock rises. Use observer mode to simulate this function.

Abstract Observer:

package observer.standard;

import java.util.ArrayList;
import java.util.List;

public abstract class Subject {
	//  Define a collection of observers
	protected List<Observer> observers = new ArrayList<>();

	// Add an observer
	public void add(Observer observer) {
		observers.add(observer);
	}

	//  Delete an observer
	public void remove(Observer observer) {
		observers.remove(observer);
	}

	//  Notify all observers
	public abstract void notifyObservers();
}

Specific observers:

package observer.standard;

public class Stock extends Subject {
	private double money = 1.0;

	//  Logic of custom notification method
	public void setMoney(double money) {
		//  Only when the current stock price rises will all observers be notified
		if (money > this.money) {
			this.money = money;
			notifyObservers();
		}
		this.money = money;

	}

	//  Implementation notification method
	@Override
	public void notifyObservers() {
		for (Observer observer : observers) {
			observer.update(money);
		}
	}
}

Abstract Observer:

package observer.standard;

public interface Observer {
	//  Update method
	public void update(double money);
}

Specific observers:

package observer.standard;

public class Investor implements Observer {
	private String name;

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

	//  Implementation update method
	@Override
	public void update(double money) {
		System.out.println(name + "The stock you are concerned about has risen, and the current price is per share" + money + "element");
	}
}

Client:

package observer.standard;

public class Client {
	public static void main(String[] args) {
		//  Simulate three users subscribing to the rise reminder of the same stock
		Observer user1 = new Investor("Space");
		Observer user2 = new Investor("Spencer");
		Observer user3 = new Investor("Alice");

		//  Add observer
		Stock stock = new Stock();
		stock.add(user1);
		stock.add(user2);
		stock.add(user3);

		//  The observer updates the status and notifies all observers
		stock.setMoney(1.12);
		System.out.println("===================");

		stock.setMoney(1.2);
		System.out.println("===================");

		//  Since the share price did not rise, the observer was not informed
		stock.setMoney(1.1);


		/**
		 * Output result:
		 * Space The stock you are concerned about has risen. The current price is 1.12 yuan per share
		 * Spencer The stock you are concerned about has risen. The current price is 1.12 yuan per share
		 * Alice The stock you are concerned about has risen. The current price is 1.12 yuan per share
		 * ===================
		 * Space The stock you are concerned about has risen. The current price is 1.2 yuan per share
		 * Spencer The stock you are concerned about has risen. The current price is 1.2 yuan per share
		 * Alice The stock you are concerned about has risen. The current price is 1.2 yuan per share
		 * ===================
		 */


	}
}


When a new investor wants to set the rise of the stock, he just needs to add it to the observer set.

When there is a new stock, it is necessary to add a new specific subject class (observed). When the new stock changes, all observers will be notified, but in fact, we only want the shareholders who pay attention to the stock to receive the message. At this time, we can use double assignment to specify the type of object (the type of observed) and then choose whether to execute the update method. Fortunately, JDK has implemented the observer function with double dispatch for us.

Built in observer mode in JDK

Specific observers:

package observer.jdk;

import java.util.Observable;

public class StockA extends Observable {
	private double money = 1.0;

	//  Logic of custom notification method
	public void setMoney(double money) {
		//  Only when the current stock price rises will all observers be notified
		if (money > this.money) {
			//  Update share price
			this.money = money;
			// The content of setting the observed has been changed
			this.setChanged();
			// Notify all observers of updates
			this.notifyObservers(money);
		}
		//  Update share price
		this.money = money;
	}
}

package observer.jdk;

import java.util.Observable;

public class StockB extends Observable {
   private double money = 1.0;

   //  Logic of custom notification method
   public void setMoney(double money) {
      //  Only when the current stock price rises will all observers be notified
      if (money > this.money) {
         //  Update share price
         this.money = money;
         // The content of setting the observed has been changed
         this.setChanged();
         // Notify all observers of updates
         this.notifyObservers(money);
      }
      //  Update share price
      this.money = money;
   }
}

Observer:

package observer.jdk;

import java.util.Observable;
import java.util.Observer;

public class Investor implements Observer {
    private String name;

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

    //  Implementation update method
    @Overrideaaa
    public void update(Observable o, Object arg) {
        //  Judge whether it is the (specific) observer who pays attention to the stock, and only observe the change of StockA
        if(o instanceof StockA){
            System.out.println(name+"Stocks you focus on A It's up. Now the price is per share"+arg+"element");
        }
    }
}

Client:

package observer.jdk;


public class Client {
	public static void main(String[] args) {
		//  Simulate three users subscribing to the rise reminder of the same stock
		Investor user1 = new Investor("Space");
		Investor user2 = new Investor("Spencer");
		Investor user3 = new Investor("Alice");

		//  Add an observer for StockA
		StockA stockA = new StockA();
		stockA.addObserver(user1);
		stockA.addObserver(user2);
		stockA.addObserver(user3);

		//  Add an observer for StockB
		StockB stockB = new StockB();
		stockB.addObserver(user1);
		stockB.addObserver(user2);
		stockB.addObserver(user3);

		//  Update StockA's share price
		System.out.println("========StockA===========");
		stockA.setMoney(1.12);
		System.out.println("===================");
		stockA.setMoney(1.2);

		//  Update the stock price of StockB. No matter the change of StockB, StockB has no output
		System.out.println("========StockB===========");
		stockB.setMoney(1.12);
		System.out.println("===================");
		//  The observer updates the status and notifies all observers
		stockB.setMoney(1.2);

		/**
		 * Output result:
		 * ========StockA===========
		 * Alice Stock A you are concerned about has risen. The current price is 1.12 yuan per share
		 * Spencer Stock A you are concerned about has risen. The current price is 1.12 yuan per share
		 * Space Stock A you are concerned about has risen. The current price is 1.12 yuan per share
		 * ===================
		 * Alice The stock A you are concerned about has risen. The current price is 1.2 yuan per share
		 * Spencer The stock A you are concerned about has risen. The current price is 1.2 yuan per share
		 * Space The stock A you are concerned about has risen. The current price is 1.2 yuan per share
		 * ========StockB===========
		 * ===================
		 */


	}
}

3, Summary

Observer mode can establish a trigger mechanism for one to many dependencies. When the observed triggers the mechanism, all observers will be notified to update. And through the built-in Java util. Observable implementation class and Java util. Observer interface can easily implement observer mode and process specific observers.

Keywords: Java Spring Design Pattern Back-end Interview

Added by allenskd on Tue, 08 Mar 2022 16:18:35 +0200