• 设计模式 - 观察者模式


    目录

    一. 前言

    二. 实现

    三. 优缺点


    一. 前言

        观察者模式属于行为型模式。在程序设计中,观察者模式通常由两个对象组成:观察者和被观察者。当被观察者状态发生改变时,它会通知所有的观察者对象,使他们能够及时做出响应,所以也被称作“发布-订阅模式”。

    二. 实现

    主题(Subject)具有注册和移除观察者、并通知所有观察者的功能,主题是通过维护一张观察者列表来实现这些操作的。
    观察者(Observer)的注册功能需要调用主题的 registerObserver() 方法。

    案例:天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,并且在将来会继续增加。

    1. public interface Subject {
    2. void resisterObserver(Observer o);
    3. void removeObserver(Observer o);
    4. void notifyObserver();
    5. }
    1. public class WeatherData implements Subject {
    2. private List observers;
    3. private float temperature;
    4. private float humidity;
    5. private float pressure;
    6. public WeatherData() {
    7. observers = new ArrayList<>();
    8. }
    9. public void setMeasurements(float temperature, float humidity, float pressure) {
    10. this.temperature = temperature;
    11. this.humidity = humidity;
    12. this.pressure = pressure;
    13. notifyObserver();
    14. }
    15. @Override
    16. public void resisterObserver(Observer o) {
    17. observers.add(o);
    18. }
    19. @Override
    20. public void removeObserver(Observer o) {
    21. int i = observers.indexOf(o);
    22. if (i >= 0) {
    23. observers.remove(i);
    24. }
    25. }
    26. @Override
    27. public void notifyObserver() {
    28. for (Observer o : observers) {
    29. o.update(temperature, humidity, pressure);
    30. }
    31. }
    32. }
    1. public interface Observer {
    2. void update(float temp, float humidity, float pressure);
    3. }
    1. public class StatisticsDisplay implements Observer {
    2. public StatisticsDisplay(Subject weatherData) {
    3. weatherData.resisterObserver(this);
    4. }
    5. @Override
    6. public void update(float temp, float humidity, float pressure) {
    7. System.out.println("StatisticsDisplay.update: " + temp + " " + humidity + " " + pressure);
    8. }
    9. }
    1. public class CurrentConditionsDisplay implements Observer {
    2. public CurrentConditionsDisplay(Subject weatherData) {
    3. weatherData.resisterObserver(this);
    4. }
    5. @Override
    6. public void update(float temp, float humidity, float pressure) {
    7. System.out.println("CurrentConditionsDisplay.update: " + temp + " " + humidity + " " + pressure);
    8. }
    9. }
    1. public class WeatherStation {
    2. public static void main(String[] args) {
    3. WeatherData weatherData = new WeatherData();
    4. CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
    5. StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
    6. weatherData.setMeasurements(0, 0, 0);
    7. weatherData.setMeasurements(1, 1, 1);
    8. }
    9. }
    1. CurrentConditionsDisplay.update: 0.0 0.0 0.0
    2. StatisticsDisplay.update: 0.0 0.0 0.0
    3. CurrentConditionsDisplay.update: 1.0 1.0 1.0
    4. StatisticsDisplay.update: 1.0 1.0 1.0

    三. 优缺点

    优点
    1. 被观察者和观察者对象之间不需要知道对方的具体实现,只需要知道对方的接口,避免了紧耦合的关系。
    2. 由于被观察者对象并不关心具体的观察者是谁,所以在程序运行的过程中,可以动态地增加或者删除观察者对象,增加了灵活性。
    3. 符合开闭原则,当需要添加新的观察者时,只需要添加一个实现观察者接口的类,而不需要修改被观察者对象的代码。
    缺点
    1. 当观察者没有被正确移除时,可能会导致内存泄漏的问题。
    2. 实现观察者模式,需要定义多个接口和类,增加了程序的复杂度。
    3. 在某些情况下,被观察者和观察者对象之间可能出现循环依赖的问题。

    JDK中的命令模式
    java.util.Observer
    java.util.EventListener
    javax.servlet.http.HttpSessionBindingListener

  • 相关阅读:
    PLC-Recorder离线分析软件Ana里为什么不能显示变量的编号?
    Mybatis 快速入门之 关联关系映射
    PyTorch深度学习实战(5)——计算机视觉基础
    1019 链表的下一个更大节点(单调栈)
    vscode的窗口下拉显示行数不够
    【SaToken使用】springboot+redis+satoken权限认证
    JavaScript实现动态时钟显示
    【LeetCode 1758】生成交替二进制字符串的最少操作数
    nodejs系列:22.koa介绍
    找不到d3dx9_37.dll,无法继续执行代码
  • 原文地址:https://blog.csdn.net/mrluo735/article/details/133673893