观察者模式实现

  1. 1. 观察者模式Overview
  2. 2. 使用场景
  3. 3. 使用目的
  4. 4. 具体实现
    1. 4.1 接口和数据对象定义
    2. 4.2 具体实现类的定义
    3. 4.3 测试
  5. Reference

1. 观察者模式Overview

  • 定义了一种一对多的交互方式,可以被观察的对象可以通知所有观察者他们期待的对象的变化,Pull vs Push.
    • 当一个对象改变状态的时候,它的所有依赖者都会收到通知并且会自动更新
  • Subject/ Observable
    • 管理某些数据
    • 当数据改变的时候,通知订阅者
  • Observer
    • 在订阅的数据发生改变了以后,得到通知

2. 使用场景

  • 出版者 + 订阅者
  • Check Java Observable, though deprecated

3. 使用目的

  • 责任的分开,只有一份数据,由Observable来进行管理,
  • Observer只是拿到了数据的更新,然后做自己特定的事情,observable完全不需要知道这里的细节。用这种方式实现了交互对象之间的松耦合

4. 具体实现

Class Diagram

4.1 接口和数据对象定义

/**
 * Observer other abilities
 */
public interface IDisplay {
    void display();
}

/**
* Observable interface, used to register/remove/notify observers 
*/
public interface IObservable {
    ActionResult registerObserver(IObserver observer);
    ActionResult removeObserver(IObserver observer);
    void notifyObservers();
}

/**
 * Observable will call update method for regiestered observer to update the status in observer side
 */
public interface IObserver {
    void update(SharebleData data);

@Data
@RequiredArgsConstructor
@AllArgsConstructor
public class SharebleData {

    Double temperature;
    Double humidity;
    Double pressure;
}

public enum Status {
    SUCCESS,
    FAILURE
}

@Data
@AllArgsConstructor
public class ActionResult {

    @NonNull
    Status status;

    @Nullable
    List<String> errorReason;

}

4.2 具体实现类的定义

public class ObservableImpl implements IObservable{

    private static List<IObserver> observerList;

    private SharebleData data;

    public ObservableImpl() {
        observerList = new ArrayList<>();
        data = new SharebleData();
    }

    public void setSharebleData(double tem, double humidity, double pressure) {
        data.setHumidity(humidity);
        data.setTemperature(tem);
        data.setPressure(pressure);
        notifyObservers();
    }

    @Override
    public ActionResult registerObserver(IObserver observer) {
        observerList.add(observer);
        return new ActionResult(Status.SUCCESS, null);
    }

    @Override
    public ActionResult removeObserver(IObserver observer) {
        observerList.remove(observer);
        return new ActionResult(Status.SUCCESS, null);
    }

    @Override
    public void notifyObservers() {
        observerList.forEach(observer -> {observer.update(data);});
    }
}

public class CurrentConditionDisplay implements IObserver, IDisplay{

    private double temp;
    private double pressure;
    private IObservable observable;

    public CurrentConditionDisplay(IObservable subject) {
        this.observable = subject;
        observable.registerObserver(this);
    }
    @Override
    public void display() {
        System.out.println(String.format("======= print out current tem and pressure! temp: %f, pressure: %f ", temp, pressure));
    }

    @Override
    public void update(SharebleData data) {
        temp = data.getTemperature();
        pressure = data.getPressure();
        display();
    }
}

4.3 测试

@RestController
public class TestController {

    @GetMapping("/observer")
    public String observer() {
        StringBuilder sb = new StringBuilder();

        ObservableImpl observable = new ObservableImpl();
        observable.setSharebleData(30, 0.7, 80);

        CurrentConditionDisplay currentConditionDisplay = new CurrentConditionDisplay(observable);
        observable.setSharebleData(31, 0.7, 80);

        observable.setSharebleData(32, 0.7, 80);

        observable.setSharebleData(33, 0.7, 80);

        return "Please check log";
    }
}

// Output from console 
======= print out current tem and pressure! temp: 31.000000, pressure: 80.000000 
======= print out current tem and pressure! temp: 32.000000, pressure: 80.000000 
======= print out current tem and pressure! temp: 33.000000, pressure: 80.000000 

Reference

  1. https://learning.oreilly.com/library/view/head-first-design/9781492077992/ch02.html

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 stone2paul@gmail.com

文章标题:观察者模式实现

文章字数:613

本文作者:Leilei Chen

发布时间:2022-09-17, 11:49:49

最后更新:2022-09-17, 11:53:15

原始链接:https://www.llchen60.com/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F-1/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏