【Java 设计模式】行为型之观察者模式

文章目录

    • 1. 定义
    • 2. 应用场景
    • 3. 代码实现
    • 结语

观察者模式(Observer Pattern)是一种行为型设计模式,用于定义一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。观察者模式提供了一种对象间的联动机制,使得一个对象的变化能够影响其他对象,而不需要它们之间显式地相互引用。在本文中,我们将深入研究Java中观察者模式的定义、结构、使用场景以及如何在实际开发中应用。

1. 定义

观察者模式是一种行为型设计模式,用于定义一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。观察者模式通常包含两个主要角色:主题(Subject)和观察者(Observer)。

  • 主题(Subject):

    维护一组观察者对象,提供添加、删除和通知观察者的方法。主题可以是具体的实现类或接口。

  • 观察者(Observer):

    定义了一个更新方法,用于在主题状态发生变化时接收通知和执行相应操作。观察者通常是一个接口,可以由具体的实现类来实现。

2. 应用场景

观察者模式通常在以下场景中使用:

  • 一对多的依赖关系:

    当一个对象的状态发生改变需要通知多个对象时,可以使用观察者模式。这样可以避免对象之间的紧耦合,提高系统的灵活性。

  • 解耦发布者和订阅者:

    当发布者和订阅者之间需要解耦时,可以使用观察者模式。发布者无需知道订阅者的具体实现,只需通知观察者即可。

  • 动态更新:

    当一个对象的状态需要动态更新,并且希望其他对象能够自动感知并作出相应的改变时,可以使用观察者模式。

3. 代码实现

下面通过一个简单的例子来演示观察者模式的实现。假设有一个新闻发布系统,我们可以使用观察者模式来让多个订阅者实时获取新闻的更新。

主题 - 新闻发布 Subject

package com.cheney.demo;interface Subject {void addObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers(String news);
}

观察者 - 订阅者 Observer

package com.cheney.demo;interface Observer {void update(String news);
}

具体主题 - 具体新闻发布 NewsPublisher

package com.cheney.demo;import java.util.ArrayList;
import java.util.List;class NewsPublisher implements Subject {private List<Observer> observers = new ArrayList<>();@Overridepublic void addObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers(String news) {for (Observer observer : observers) {observer.update(news);}}public void publishNews(String news) {System.out.println("发布消息: " + news);notifyObservers(news);}
}

具体观察者 - 具体订阅者 NewsSubscriber

package com.cheney.demo;class NewsSubscriber implements Observer {private String name;public NewsSubscriber(String name) {this.name = name;}@Overridepublic void update(String news) {System.out.println(name + " 订阅消息: " + news);}
}

客户端启动类 Main

package com.cheney.demo;public class Main {public static void main(String[] args) {// 使用观察者模式实现新闻发布和订阅NewsPublisher newsPublisher = new NewsPublisher();Observer subscriber1 = new NewsSubscriber("订阅者1");Observer subscriber2 = new NewsSubscriber("订阅者2");newsPublisher.addObserver(subscriber1);newsPublisher.addObserver(subscriber2);newsPublisher.publishNews("突发新闻:重大事件!");// 移除订阅者newsPublisher.removeObserver(subscriber1);newsPublisher.publishNews("更新:天气预报");}
}

在上述例子中,Subject 是主题接口,定义了添加、移除和通知观察者的方法。Observer 是观察者接口,定义了更新方法。NewsPublisher 是具体主题,实现了主题接口,并维护了一组观察者。NewsSubscriber 是具体观察者,实现了观察者接口,表示订阅者。

在客户端中,我们使用观察者模式实现了新闻发布和订阅。当新闻发布时,所有订阅者会收到通知并更新。通过这种方式,发布者和订阅者之间实现了解耦,新闻发布系统更加灵活和可维护。

结语

观察者模式是一种用于定义对象间一对多的依赖关系的设计模式。通过观察者模式,可以实现发布者和订阅者之间的解耦,提高系统的灵活性和可维护性。在实际开发中,观察者模式常被用于实现事件处理、消息通知等场景。通过合理使用观察者模式,可以使系统更加可扩展,降低对象之间的耦合度。

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

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

相关文章

WordPress 站点 Gravatar 头像不显示的解决方法

最近发现博客评论头像无法显示&#xff0c;不管是前台还是后台都不显示&#xff0c;哪怕是做了 Gravatar 头像本地缓存也不显示&#xff0c;访问 Gravatar 头像官方服务器也打不开&#xff0c;这怎么办&#xff1f;要么自定义头像&#xff0c;要么修改 Gravatar 头像的官方地址…

【Java网络编程02】套接字编程

【Java网络编程02】套接字编程 1. Socket套接字 概念&#xff1a;Socket套接字&#xff0c;就是系统提供用于实现网络通信的技术&#xff0c;是基于TCP/IP协议的网络通信基本操作单元。基于Socket套接字的网络程序开发就是网络编程。 分类&#xff1a; 我们可以把Socket套接字…

docker 部署 sentinel

docker 部署 sentinel 环境安装 拉取镜像 目前稳定的版本是1.8.0 docker pull bladex/sentinel-dashboard:1.8.0启动服务 docker run --name sentinel -p 8858:8858 -td bladex/sentinel-dashboard:1.8.0登录 登录的时候账号和密码都是sentinel

算法训练营Day45

#Java #动态规划 Feeling and experiences&#xff1a; 最长公共子序列&#xff1a;力扣题目链接 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新…

泛型..

1.泛型 所谓泛型 其实就是一种类型参数(我们平常所见到的参数指的就是方法中的参数 他接收有外界传递来的值 然后在方法中进行使用) 并且还提高了代码的复用率 何以见得提高了代码的复用率 其实就是通过对比使用了泛型技术和没有使用泛型技术之间的区别&#xff1a; 以下是没有…

QTcpSocket 对象的可工作线程

QTcpSocket 对象的可工作线程: QTcpSocket 对象创建成功&#xff0c;并设置好底层socket描述符后&#xff1b;在qt中只能在一个线程中工作【即收发网络数据】这个线程就是创建这个QTcpSocket对象的线程&#xff0c;原理上这就与这个对象依附线程是同一个线程&#xff1b;但是注…

windows如何切换访问NAS共享文件夹用户

从资源管理器对NAS共享文件夹输入用户名与密码进行访问后&#xff0c;想切换访问用户&#xff0c;搜索了一圈&#xff0c;网上介绍的方法都无效&#xff0c;最后只能注销windows7登陆&#xff0c;然后重新登陆&#xff0c;再访问NAS共享时才能切换用户&#xff0c;各位观众如有…

深入理解与运用Lombok的@Cleanup注解:自动化资源管理利器

前言 在Java编程中&#xff0c;正确地管理和释放诸如文件流、数据库连接等资源至关重要。若处理不当&#xff0c;可能会引发内存泄漏或系统资源耗尽等问题。为此&#xff0c;Lombok库提供了一个名为Cleanup的便捷注解&#xff0c;它允许我们以简洁且安全的方式自动关闭实现了j…

Linux C语言开发(九)链表

目录 一.前言 二.链表构建 一.前言 C语言的链表是一种常见且实用的数据结构,它用于存储和管理数据元素。链表由一系列节点组成,每个节点包含两个部分:数据域和指针域。数据域用于存储实际的数据元素,而指针域则用于指向链表中的下一个节点。 链表的主要特点是其存储空间的…

练习题 有奖问答

题目 问题描述 小蓝正在参与一个现场问答的节目。活动中一共有 3030 道题目, 每题只有答对和答错两种情况, 每答对一题得 10 分&#xff0c;答错一题分数归零。 小蓝可以在任意时刻结束答题并获得目前分数对应的奖项&#xff0c;之后不能再答任何题目。最高奖项需要 100 分,…

深度学习记录--Momentum gradient descent

Momentum gradient descent 正常的梯度下降无法使用更大的学习率&#xff0c;因为学习率过大可能导致偏离函数范围&#xff0c;这种上下波动导致学习率无法得到提高&#xff0c;速度因此减慢(下图蓝色曲线) 为了减小波动&#xff0c;同时加快速率&#xff0c;可以使用momentum…

【软件测试】学习笔记-制定性能测试的目标

之前有同学交流过&#xff0c;在测试执行过程中他并不清楚测试得到的结果到底能不能满足这次活动的需求。经过追问&#xff0c;发现他连本次活动规则涉及的模块和接口都不是十分清楚&#xff0c;像这样的测试就是没有做性能测试目标的分析。虽然说做了性能测试&#xff0c;但几…

学习CANopen --- [12] Abort报文

当我们使用SDO进行读写操作时&#xff0c;有时device会返回abort报文&#xff0c;意味着本次SDO读写失败。本文使用例子来讲解Abort报文&#xff0c;以及如何解读失败原因。 一 Device例子 下面是device的python代码&#xff0c;文件名叫device.py&#xff0c;device的CANopen…

Kotlin协程学习之-02

协程的基本使用 GlobalScope.launch 生命周期与进程一致&#xff0c;且无法取消 runBlocking 会阻塞线程&#xff0c;一般在测试阶段可以使用 val coroutineScope CoroutineScope(context) coroutineScope.launch 通过context参数去管理和控制协程的生命周期 用法 va…

Linux配置主机名-使用主机名访问服务器

主要需要对Hosts文件进行操作&#xff0c; Hosts是一个没有扩展名的系统文件&#xff0c;可以用记事本等工具打开&#xff0c;其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”&#xff0c; 先将自己的主机名设置成有意义&#xff0c;别人好记的样子&a…

上位机图像处理和嵌入式模块部署(开篇)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 图像处理是现实生活当中很实用的一门技术。工业上一般采用的是机器视觉&#xff0c;以传统算法和光源控制为主&#xff0c;部分采用了深度学习技术…

【51单片机】外部中断

0、前言 参考&#xff1a;普中 51 单片机开发攻略 第16章 及17章 1、硬件 2、软件 #include <reg52.h> #include <intrins.h> #include "delayms.h"typedef unsigned char u8; typedef unsigned int u16;sbit led P2^0; sbit key3 P3^2;//外部中断…

【深度学习】详解利用Matlab和Python中 LSTM 网络实现序列分类

🔗 运行环境:Matlab、Python 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 🔐#### 防伪水印——左手の明天 ####🔐 💗 大家好🤗🤗🤗,我是左手の明天!好久不见💗 💗今天分享Matlab深度学习—— LSTM 网络实现序列分

【深度学习:数据增强 】提高标记数据质量的 5 种方法

【深度学习&#xff1a;数据增强 】提高标记数据质量的 5 种方法 计算机视觉中常见的数据错误和质量问题&#xff1f;为什么需要提高数据集的质量&#xff1f;提高标记数据质量的五种方法使用复杂的本体结构作为标签人工智能辅助标签识别标签错误的数据改进注释者管理 计算机视…

spark 入门教程

一、安装scala环境 官网下载地址 Download | The Scala Programming Language,本次使用版本为sacla2.11.12,将压缩包解压至指定目录&#xff0c;配置好环境变量&#xff0c;控制台验证是否安环境是否可用&#xff1a; 二、添加pom依赖 创建一个maven项目 1、添加scala的sdk依…