[Design Patterns] Chapter 22 Observer Pattern

1. Overview of the Observer Pattern

The Observer pattern is one of the most frequently used design patterns. It is used to establish a dependency relationship between objects. When an object changes, it will automatically notify other objects, and other objects will respond accordingly.

Definition:
Observer pattern : Define a one-to-many dependency relationship between objects, so that whenever an object changes, its related dependent objects are automatically updated by being notified.

The aliases of the observer mode include the Publish-Subscribe mode, the Model-view mode, the Source-Listener mode, and the Dependents mode.

2. The structure and implementation of the observer mode

2.1 Structure of Observer Pattern

Observer mode contains the following 4 roles:

  1. Subject (target): The target is also called the subject, which refers to the object to be observed.
  2. ConcreteSubject: ConcreteSubject is a subclass of Target. It usually contains data that changes frequently, and its observers are notified when its state changes.
  3. Observer (observer): The observer will respond to changes in the observed target.
  4. ConcreteObserver (concrete observer): The concrete observer is a subclass of the observer, which implements the method of updating data declared in the observer.

2.2 Implementation of Observer Pattern

JDK provides support for the observer mode. The Observable class and the Observer interface are provided in the java.util package of the JDK. The Observable class acts as an abstract observation target class, and the Observer interface acts as an abstract observer.

The following is a case of implementing the observer mode by using the classes and interfaces provided by the JDK.

// concrete target class

import java.math.BigDecimal;
import java.util.Observable;

/**
 * 股票,充当具体的观察目标类
 * 继承jdk自带的抽象观察目标类
 */
public class Stock extends Observable {

    //股票价格
    private BigDecimal price;

    public Stock(BigDecimal price){
        this.price = price;
    }

    /**
     * 模拟股票涨跌情况,如果有超过涨跌幅达到5%及其以上,
     * 就通知购买了股票的股民,并告知当前股票价格情况
     *
     * @param scope 涨跌幅,单位%,比如scope=0.02,就是涨了2%
     */
    public void advancesVersusDeclines(BigDecimal scope) {
        price = price.multiply(scope).add(price);

        if (scope.doubleValue() >= 0.05) {
            super.setChanged();
            super.notifyObservers(price);
        }
    }

    public BigDecimal getPrice() {
        return price;
    }


}

// concrete observer

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

/**
 * 股民,充当具体观察对象
 * 继承jdk自带的抽象观察者
 */
public class Investor implements Observer {

    private String name;

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

    @Override
    public void update(Observable o, Object arg) {
        System.out.println(name + "你好,股票涨跌幅超过5%,当前股票价格为:" + arg);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

//client

public class Client {

    public static void main(String[] args) {

        /**
         * 案例需求描述:
         * 某股票软件需要提供以下功能:
         * 当股票购买者所购买的某只股票的价格变化幅度达到5%,系统将自动发送通知(包括新价格)给购买该股票的股民。
         * 试适用观察者模式设计并实现该功能。
         */


        //发布一个新的股票,并设置股票初始价格
        Stock stock = new Stock(new BigDecimal("10"));

        //定义股民
        Investor zhangsan = new Investor("张三");
        Investor lisi = new Investor("李四");
        Investor wangwu = new Investor("王五");

        //股名购买了这只股票
        stock.addObserver(zhangsan);
        stock.addObserver(lisi);
        stock.addObserver(wangwu);

        //模拟股票实时变化情况
        stock.advancesVersusDeclines(new BigDecimal("0.02"));
        stock.advancesVersusDeclines(new BigDecimal("0.0345"));
        stock.advancesVersusDeclines(new BigDecimal("0.0512"));
        stock.advancesVersusDeclines(new BigDecimal("0.0312"));

    }

}

3. The advantages and disadvantages of the observer mode and the applicable environment

3.1 Advantages of the observer pattern

  1. Realize the separation of presentation layer and data logic layer;
  2. Create an abstract coupling between the observation target and the observer;
  3. Support broadcast communication and conform to the principle of opening and closing;

3.2 Disadvantages of the observer pattern

  1. It takes a lot of time to notify all observers;
  2. If there is a cyclic call, it may cause the system to crash;
  3. There is no corresponding mechanism for the observer to know how the observed target object has changed, but only know that the observed target has changed;

3.3 Applicable environment of the observer mode

  1. An abstract model has two aspects, one of which depends on the other, and encapsulating these two aspects in independent objects allows them to be changed and reused independently;
  2. A change to one object will cause one or more other objects to change as well, without knowing exactly how many objects will change or who those objects are;
  3. A trigger chain needs to be created in the system.

[References]:
This article is based on the study notes of Liu Wei's "Java Design Patterns". It is for learning purposes only. Do not use it for other purposes. Please respect intellectual property rights.

[Code warehouse for this article]: https://gitee.com/xiongbomy/java-design-pattern.git

Guess you like

Origin blog.csdn.net/weixin_44143114/article/details/126533126