Observer mode of design mode

Keywords: Design Pattern

In the real world, many objects do not exist independently, and a change in the behavior of one of them may lead to a change in the behavior of one or more other objects. For example, when the price of a commodity rises, some businesses are happy and consumers are sad. Also, when we drive to an intersection, we stop at a red light and go at a green light.There are many other examples, such as stock prices and shareholders, WeChat public numbers and WeChat subscribers, weather forecasts and listeners from meteorological offices, thieves and police, etc.

The same is true in the software world, for example, the relationship between data in Excel and polyline, pie and column charts; the relationship between models and views in MVC mode; the event source and event handler in event model. All of these are very convenient to implement in observer mode.

Definition and characteristics of patterns

Definition of Observer mode:

A one-to-many dependency exists between multiple objects. When the state of an object changes, all objects that depend on it are notified and updated automatically. This mode is sometimes called publish-subscribe mode, Model-View mode, and it is an object behavior mode.

Advantages and disadvantages of the observer model:

Advantage

  1. Decreases the coupling between the target and the observer, which is abstract. Compliant with the principle of inversion of dependency.
  2. A trigger mechanism is established between the target and the observer.

shortcoming

  1. The dependency between the target and the observer is not completely broken, and circular references may occur.
  2. When there are many observer objects, the publication of notifications takes a lot of time, which affects the efficiency of the program.

Structure and implementation of patterns

When implementing the observer mode, it is important to note that there is no direct call between the specific target object and the specific observer object, otherwise they will be tightly coupled, which violates the object-oriented design principles.

1.The structure of the pattern

The main roles of the observer mode are as follows.

  1. Subject role: Also known as abstract target class, it provides an abstract method for saving aggregated classes of observer objects, adding and deleting observer objects, and notifying all observers.
  2. Specific Theme (Concrete)
    Subject) Role: Also known as a specific target class, it implements a notification method within an abstract target to notify all registered observer objects when the internal state of a specific topic changes.
  3. The Observer role: It is an abstract class or interface that contains an abstract method to update itself and is invoked when notified of changes to a specific topic.
  4. Specific Observer role: Implement the abstract method defined in the abstract observer to update its own state when notified of changes to the target.

2.Implementation of patterns

The implementation code for the observer mode is as follows:

package net.biancheng.c.observer;
import java.util.*;
public class ObserverPattern {
    public static void main(String[] args) {
        Subject subject = new ConcreteSubject();
        Observer obs1 = new ConcreteObserver1();
        Observer obs2 = new ConcreteObserver2();
        subject.add(obs1);
        subject.add(obs2);
        subject.notifyObserver();
    }
}
//Abstract Target
abstract class Subject {
    protected List<Observer> observers = new ArrayList<Observer>();
    //Increase Observer Method
    public void add(Observer observer) {
        observers.add(observer);
    }
    //Delete Observer Method
    public void remove(Observer observer) {
        observers.remove(observer);
    }
    public abstract void notifyObserver(); //Notify Observer Method
}
//Specific objectives
class ConcreteSubject extends Subject {
    public void notifyObserver() {
        System.out.println("Target change...");
        System.out.println("--------------");
        for (Object obs : observers) {
            ((Observer) obs).response();
        }
    }
}
//Abstract observer
interface Observer {
    void response(); //reaction
}
//Specific Observer 1
class ConcreteObserver1 implements Observer {
    public void response() {
        System.out.println("Specific observer 1 responds!");
    }
}
//Specific Observer 1
class ConcreteObserver2 implements Observer {
    public void response() {
        System.out.println("Specific observer 2 responds!");
    }
}

The program runs as follows:

Target change...
--------------
Specific observer 1 responds!
Specific observer 2 responds!

Application examples of patterns

[Example 1] Using the observer model, a program is designed to analyze the impact of the appreciation or depreciation of the Renminbi exchange rate on the cost of imported products of an importing company or the income of export products of an exporting company, as well as the company's profit margin.

Analysis: When the "Renminbi exchange rate" rises, the cost of imported products of import companies decreases and the profit margin increases, the revenue of export products of export companies decreases and the profit margin decreases. When the "Renminbi exchange rate" depreciates, the cost of imported products of import companies increases and the profit margin decreases, while the revenue of export products of export companies increases and the profit margin increases.

Here the Rate class is the abstract target class, which contains methods to keep the List of the observer (Company) and to increase/delete the observer, as well as the abstract method of exchange rate change(int number); while the RMBrate class is the specific target, which achieves the change(int number) of the parent class.The method is to pass through related companies when the exchange rate of Renminbi changes; the Company class is an abstract observer, which defines an abstract method response(int number) on exchange rate response; the Import Company class and the ExportCompany class are concrete observer classes, which implement the response(int number) of the parent class.Method, that is, when they receive notification of exchange rate changes as a corresponding response. Figure 2 shows their structure.

The program code is as follows:

package net.biancheng.c.observer;
import java.util.*;
public class RMBrateTest {
    public static void main(String[] args) {
        Rate rate = new RMBrate();
        Company watcher1 = new ImportCompany();
        Company watcher2 = new ExportCompany();
        rate.add(watcher1);
        rate.add(watcher2);
        rate.change(10);
        rate.change(-9);
    }
}
//Abstract Target: Exchange Rate
abstract class Rate {
    protected List<Company> companys = new ArrayList<Company>();
    //Increase Observer Method
    public void add(Company company) {
        companys.add(company);
    }
    //Delete Observer Method
    public void remove(Company company) {
        companys.remove(company);
    }
    public abstract void change(int number);
}
//Specific objectives: Renminbi exchange rate
class RMBrate extends Rate {
    public void change(int number) {
        for (Company obs : companys) {
            ((Company) obs).response(number);
        }
    }
}
//Abstract Observer: Company
interface Company {
    void response(int number);
}
//Specific Observer 1: Import Company
class ImportCompany implements Company {
    public void response(int number) {
        if (number > 0) {
            System.out.println("Renminbi exchange rate appreciation" + number + "Base point, which reduces the cost of imported products and increases the profit margin of importing companies.");
        } else if (number < 0) {
            System.out.println("Devaluation of Renminbi Exchange Rate" + (-number) + "Base point, which increases the cost of imported products and reduces the profit margin of importing companies.");
        }
    }
}
//Specific Observer 2: Export Company
class ExportCompany implements Company {
    public void response(int number) {
        if (number > 0) {
            System.out.println("Renminbi exchange rate appreciation" + number + "Base point, which reduces the revenue of export products and the profit margin of export companies.");
        } else if (number < 0) {
            System.out.println("Devaluation of Renminbi Exchange Rate" + (-number) + "Base point, which increases the revenue of export products and the profit margin of export companies.");
        }
    }
}

The program runs as follows:

The appreciation of the RMB exchange rate by 10 basis points has reduced the cost of imported products and increased the profit margin of importing companies.
The appreciation of the Renminbi exchange rate by 10 basis points has reduced the revenue of export products and the profit margin of export companies.
The depreciation of the Renminbi exchange rate by 9 basis points has increased the cost of imported products and reduced the profit margin of importing companies.
The depreciation of the Renminbi exchange rate by 9 basis points has increased the revenue of export products and the profit margin of export companies.

The most frequently used observer mode in software development is event handling in form programming. All components in the form are "event source", which is also the target object, while the object of event handler class is the specific observer object. The following is an example of event handler for a school bell to illustrate how Event Handling Model works in Windows.

Scenarios for applying patterns

In software systems, when one party's behavior depends on the other party's behavior changes, the observer mode can be used to loosely couple the two parties so that one party's change can be notified to the other party of interest and the other party can respond to it.

From the previous analysis and application examples, it is known that the observer pattern is suitable for the following situations.

  1. There is a one-to-many relationship between objects, and changes in the state of one object can affect other objects.
  2. When an abstract model has two aspects, one of which depends on the other, it can be encapsulated in separate objects so that they can be independently changed and reused.
  3. To achieve a function similar to that of a broadcasting mechanism, you do not need to know the specific listener. You only need to distribute the broadcasting, and the objects of interest in the system will receive it automatically.
  4. Multilevel nested use forms a chain trigger mechanism that enables events to be notified across two observer types.

Extension of patterns

In Java, observer modes are defined through java.util.Observable classes and java.util.Observer interfaces, and you can write observer mode instances as long as you implement their subclasses.

1.Observable class

The Observable class is an abstract target class that has a Vector vector to hold all observer objects to be notified. Here are three of its most important methods.

  1. void addObserver(Observer o) method: Used to add a new observer object to a vector.
  2. void notifyObservers(Object arg) method: calls update() of all observer objects in the vector
    Method that notifies them that the data has changed. Observers who join vectors are usually notified the later.
  3. void setChange() method: used to set a boolean
    An internal flag bit of a type indicating that the target object has changed. NotfyObservers() notifies the observer when it is true.

2.Observer interface

The Observer interface is an abstract observer that monitors changes in the target object. When the target object changes, the observer is notified and the void update(Observable o,Object arg) method is called to do the appropriate work.

Notes: 1. JAVA already has support classes for the observer mode. 2. Avoid circular references. 3. If executed sequentially, an observer error will cause the system to become jammed, generally in an asynchronous manner.

Posted by findapollo on Tue, 14 Sep 2021 09:41:22 -0700