设计模式 - 观察者模式

news2024/11/24 6:30:19

目录

一. 前言

二. 实现

三. 优缺点


一. 前言

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

二. 实现

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

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

public interface Subject {
    void resisterObserver(Observer o);

    void removeObserver(Observer o);

    void notifyObserver();
}
public class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() {
        observers = new ArrayList<>();
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        notifyObserver();
    }

    @Override
    public void resisterObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if (i >= 0) {
            observers.remove(i);
        }
    }

    @Override
    public void notifyObserver() {
        for (Observer o : observers) {
            o.update(temperature, humidity, pressure);
        }
    }
}
public interface Observer {
    void update(float temp, float humidity, float pressure);
}
public class StatisticsDisplay implements Observer {
    public StatisticsDisplay(Subject weatherData) {
        weatherData.resisterObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        System.out.println("StatisticsDisplay.update: " + temp + " " + humidity + " " + pressure);
    }
}
public class CurrentConditionsDisplay implements Observer {
    public CurrentConditionsDisplay(Subject weatherData) {
        weatherData.resisterObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        System.out.println("CurrentConditionsDisplay.update: " + temp + " " + humidity + " " + pressure);
    }
}
public class WeatherStation {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);

        weatherData.setMeasurements(0, 0, 0);
        weatherData.setMeasurements(1, 1, 1);
    }
}
CurrentConditionsDisplay.update: 0.0 0.0 0.0
StatisticsDisplay.update: 0.0 0.0 0.0
CurrentConditionsDisplay.update: 1.0 1.0 1.0
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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1068686.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

攻防世界 Web_python_template_injection SSTI printer方法

这题挺简单的 就是记录一下不同方法的rce python_template_injection ssti了 {{.__class__.__mro__[2].__subclasses__()}} 然后用脚本跑可以知道是 71 {{.__class__.__mro__[2].__subclasses__()[71]}} 然后直接 init {{.__class__.__mro__[2].__subclasses__()[71].__i…

18373-2013 印制板用E玻璃纤维布 知识梳理

声明 本文是学习GB-T 18373-2013 印制板用E玻璃纤维布.pdf而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了印制板用E 玻璃纤维布的定义、代号与规格、要求、试验方法、检验规则、标志、包装、 运输和贮存。 本标准适用于以E 玻璃…

移远通信:探索智慧支付新方式,创新智慧金融新格局

回顾支付工具的演变历程&#xff0c;从刷卡支付到扫码支付&#xff0c;再到 “即拿即走”的自动支付模式创新&#xff0c;货币的电子化程度一直在层层深入。这其中&#xff0c;物联网技术的作用不可言喻。 当下&#xff0c;伴随着物联网行业自身的变革与创新&#xff0c;以连接…

MySql8.0 驱动编译和使用 - Qt mingw73_32

一、开发背景 现在已经有 MySql8.0.33 是 64 位的数据库&#xff0c;仅支持 64 位的程序&#xff0c;但是当前 Qt 程序编译环境是 mingw73_32&#xff0c;所以需要编译 32 位的 MySql 驱动库 二、开发环境 QtCreator4.8.2 Qt5.12.2 MySql8.0.33 三、实现步骤 1、下载 MySql…

halcon 算子set_display_font

set_display_font 算子&#xff1a;set_display_font( : : WindowHandle, Size, Font, Bold, Slant : ) 示例&#xff1a;set_display_font (200000, 24, ‘mono’, ‘true’, ‘false’) 200000&#xff08;输入参数1&#xff09;&#xff1a;输入窗口句柄 24&#xff08;…

Git从本地库撤销已经添加的文件或目录

场景 在提交时, 误将一个目录添加到了暂存区, 而且commit 了本地库,同批次commit 的还有其他需要提交的文件。 commit 之后发现这个目录下所有的文件都不需要提交, 现在需要撤销这个提交, 使这个目录不被push到远端库。 这里以远端服务器github 为例,在Git GUI下看到的…

stm32之freeRTOS驱动小车

该文章记录将stm32之智能小车总结移植到freeRTOS上&#xff0c;期间也遇到了好些问题&#xff0c;这里做下记录。也是对freeRTOS的一个应用实践。 一、freeRTOS工程的创建 工程是利用CubeMX进行创建的&#xff0c;挺简单的&#xff0c;有空再试下手动移植freeRTOS。 启用软件定…

mysql中的各种日志

错误日志 错误日志是MySQL中最重要的日志之一,它记录了当mysqld启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时,建议首先查看此日志。 该日志是默认开启的&#xff0c;默认存放目录/var/log/,默认的日志文件名为my…

300.最长递增子序列

贪心二分查找 贪心&#xff1a;上升子序列尽可能长&#xff0c;序列上升尽可能慢&#xff0c;每次在上升子序列后加上的那个数尽可能小数组d&#xff0c;长度为len的最长上升子序列&#xff0c;d[i]为长度为i的最长上升子序列的末尾元素最小值&#xff0c;起始len1&#xff0c…

Python--入门

标识符 标识符由字母&#xff0c;数字&#xff0c;下划线_组成 第一个字符不能是数字&#xff0c;必须是字母或下划线 标识符区分大小写 关键字 关键字即保留字&#xff0c;定义标识符时不能使用关键字&#xff0c;python中的关键字如下图 注释 python中的单行注释用 # 多行注…

口袋参谋:0销量宝贝,如何快速获的流量曝光?

​如今的淘宝天猫&#xff0c;新品前期无销量前提下&#xff0c;是无法获得任何流量的&#xff0c;而唯一快速破零的方法&#xff1a;只有S单&#xff01; 常规的搜索S单&#xff0c;是无法找到宝贝的&#xff0c;如果使用全标题、半标题&#xff0c;直接就会触发搜索降权&…

ssm+vue的公司人力资源管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的公司人力资源管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结…

LLMs 生成式人工智能项目生命周期备忘单Generative AI Project Lifecycle Cheat Sheet

到目前为止&#xff0c;在本课程中&#xff0c;从选择模型到微调模型&#xff0c;再到将其与人类偏好对齐&#xff0c;这一切都将在您部署应用程序之前发生。为了帮助您规划生成式AI项目生命周期的各个阶段&#xff0c;这个速查表提供了每个工作阶段所需的时间和精力的一些指示…

python学习之5个让日常编码更方便简单的库

今天为大家分享 5 个让日常编码更简单的 Python 库&#xff0c;全文3900字&#xff0c;阅读15分钟。 一、sh https://github.com/amoffat/sh 如果曾经在 Python 中使用过 subprocess 库&#xff0c;那么我们很有可能对它感到失望&#xff0c;它不是最直观的库&#xff0c;可…

Centos7安装docker 和docker-compose记录(0报错顺利安装)

文章目录 前言一、docker的安装二、docker-compose的安装总结 前言 我居然没有记录过Centos7安装docker的笔记&#xff0c;真是不可思议。每次vps安装docker都要看网上的文章&#xff0c;而且都非常坑&#xff0c;方法千奇百怪&#xff0c;最后还是决定自己来记录一个完整又方…

Jupyter notebook怎么设置自动跳转问题

1.点击开始&#xff0c;就可以看到Jupyter&#xff0c;然后点击 2.结果就这样&#xff1a; 3你可以复制地址到浏览器&#xff0c;结果&#xff1a; 但是这么做很麻烦&#xff0c;所以有没有更好的办法呢&#xff1f;当然有下面就开始介绍 1.打开cmd(winr,输入cmd),输入以下命令…

第二证券:突发!A股T+0?刚刚,紧急回应!

沪深生意所急迫回应 6日&#xff0c;商场传出一个消息&#xff0c;传延伸A股生意时刻和部分票可日内T0一次。一个版本是提早至9点&#xff0c;然后下午延伸至15&#xff1a;30&#xff0c;另一个版本是上午推延至12点&#xff0c;下午延伸至16&#xff1a;00。 7日&#xff0…

TimeWise-Jira工时管理插件6.0.0发布!对比测评某知名工时插件,谁的数据处理性能更胜一筹?

近期&#xff0c;龙智自研插件TimeWise for Jira&#xff08;Jira工时管理插件&#xff09;发布了重要更新——6.0.0版本。这次升级主要针对报表性能做出了优化与提升。 对于企业级应用而言&#xff0c;具高效处理大规模数据的能力是最为关键。龙智深谙国内用户需求&#xff0…

阿里云关系型数据库RDS详细介绍PolarDB_MySQL_MariaDB_SQL Server_PostgreSQL

阿里云RDS关系型数据库大全&#xff0c;关系型数据库包括MySQL版、PolarDB、PostgreSQL、SQL Server和MariaDB等&#xff0c;NoSQL数据库如Redis、Tair、Lindorm和MongoDB&#xff0c;阿里云百科分享阿里云RDS关系型数据库大全&#xff1a; 目录 阿里云RDS关系型数据库大全 …

【Axure高保真原型】自适应多行输入框

今天和大家分享自适应多行文本框的原型模板&#xff0c;我们可以在输入框里输入文字&#xff0c;随着文字的数量&#xff0c;输入框的高度也会自动调整……具体效果可以打开下方原型地址体验或者点击下方视频观看 【原型效果】 【Axure高保真原型】自适应多行输入框 【原型预览…