当前位置: 首页 > news >正文

基于枚举实现的观察者模式


文章目录

  • 前言
  • 一、观察者
    • 1.定义一个观察者接口
    • 2.察者接口具体实现类
  • 二、主题
    • 1.定义一个主题接口
    • 2.主题接口具体实现类
  • 三、枚举维护观察者
    • 1.定义枚举类维护观察者
  • 四、观察者模式测试
    • 1.定义观察者模式测试接口
    • 2.观察者模式测试运行结果


前言

本文介绍使用枚举的方式实现的观察者模式,简单易用,容易维护,非常适合日常的开发使用。


一、观察者

1.定义一个观察者接口

//  定义一个观察者接口,用于观察主题对象的状态变化
public interface Observer {// 发布消息void update(String message);}

2.察者接口具体实现类

package com.jareny.jave.design.observer.object.base;//  实现观察者接口的具体类,用于观察主题对象的状态变化
public class ConcreteObserver implements Observer{@Overridepublic void update(String message) {System.out.println("观察到主题对象的状态变化,具体类收到通知:" + message);}
}

二、主题

1.定义一个主题接口

package com.jareny.jave.design.observer.object.base;//  定义一个主题接口,被观察者接口,用于通知观察者对象状态变化
public interface Subject {//  注册观察者void registerObserver(Observer observer);//  删除观察者void removeObserver(Observer observer);//  通知观察者void notifyObservers(String message);}

2.主题接口具体实现类

package com.jareny.jave.design.observer.object.base;import java.util.ArrayList;
import java.util.List;//  实现主题接口,被观察者接口的具体类,用于通知观察者对象状态变化
public class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers(String message) {observers.forEach(observer->observer.update(message));}}

三、枚举维护观察者

1.定义枚举类维护观察者

package com.jareny.jave.design.observer.object.enums;import com.jareny.jave.design.observer.object.base.ConcreteObserver;
import com.jareny.jave.design.observer.object.base.Observer;
import com.jareny.jave.design.observer.object.base.Subject;
import lombok.AllArgsConstructor;
import lombok.Getter;import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;@Getter
@AllArgsConstructor
public enum ObserverEnum {/*** 第一个观察者*/Observer1("张三","学生"){@Overridepublic void register(Subject subject) {// 创建观察者对象1Observer observer = new ConcreteObserver();// 主题对象注册观察者对象1subject.registerObserver(observer);}},/*** 第二个观察者*/Observer2("李四","老师"){@Overridepublic void register(Subject subject) {// 创建观察者对象2Observer observer = new ConcreteObserver();// 主题对象注册观察者对象2subject.registerObserver(observer);}},;//  名称private String name;//  类型private String type;/*** 注册观察者* @param subject*/public abstract void register(Subject subject);/*** 获取所以的观察者* @return*/public static List<ObserverEnum> getObserverEnumList(){return Stream.of(values()).collect(Collectors.toList());}}

四、观察者模式测试

1.定义观察者模式测试接口


package com.jareny.jave.design.observer.object.enums;import com.jareny.jave.design.observer.object.base.ConcreteObserver;
import com.jareny.jave.design.observer.object.base.ConcreteSubject;
import com.jareny.jave.design.observer.object.base.Observer;
import com.jareny.jave.design.observer.object.base.Subject;import java.util.List;public class ObserverEnumExample {public static void main(String[] args) {// 创建主题对象Subject subject = new ConcreteSubject();// 创建观察者对象列表List<ObserverEnum> observerEnumList = ObserverEnum.getObserverEnumList();// 观察者对象全部注册到主题对象observerEnumList.forEach(observer->observer.register(subject));// 主题对象通知所有观察者对象状态变化subject.notifyObservers("主题对象状态发生变化!");}
}

使用枚举,将观察者注册到订阅的主题种


2.观察者模式测试运行结果

运行程序,得到以下结果

观察到主题对象的状态变化,具体类收到通知:主题对象状态发生变化!
观察到主题对象的状态变化,具体类收到通知:主题对象状态发生变化!

相关文章:

基于枚举实现的观察者模式

文章目录 前言一、观察者1.定义一个观察者接口2.察者接口具体实现类 二、主题1.定义一个主题接口2.主题接口具体实现类 三、枚举维护观察者1.定义枚举类维护观察者 四、观察者模式测试1.定义观察者模式测试接口2.观察者模式测试运行结果 前言 本文介绍使用枚举的方式实现的观察…...

基于神经网络的图像识别研究

基于神经网络的图像识别是计算机视觉领域的一个热门研究方向&#xff0c;尤其是深度学习技术的兴起。以下是一些与基于神经网络的图像识别相关的关键主题和研究方向&#xff1a; 1. 卷积神经网络&#xff08;CNN&#xff09;&#xff1a; CNN是图像识别领域最重要的神经网络之…...

基于SSM的工资管理系统

基于SSM的工资管理系统 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 登录界面 管理员界面 通知公告 考勤管理 工资管理 请假管理 摘要 基于SSM&#xff08;Spring、S…...

微服务负载均衡实践

概述 本文介绍微服务的服务调用和负载均衡&#xff0c;使用spring cloud的loadbalancer及openfeign两种技术来实现。 本文的操作是在微服务的初步使用的基础上进行。 环境说明 jdk1.8 maven3.6.3 mysql8 spring cloud2021.0.8 spring boot2.7.12 idea2022 步骤 改造Eu…...

php定时任务

PHP实现执行定时任务的几种思路详解_php 精准定时任务_我是高手高手高高手的博客-CSDN博客 1.Linux服务器上使用CronTab定时执行php 我们先从相对比较复杂的服务器执行php谈起。服务器上安装了php&#xff0c;就可以执行php文件&#xff0c;无论是否安装了nginx或Apache这样的…...

2.2 如何使用FlinkSQL读取写入到文件系统(HDFS\Local\Hive)

目录 1、文件系统 SQL 连接器 2、如何指定文件系统类型 3、如何指定文件格式 4、读取文件系统 4.1 开启 目录监控 4.2 可用的 Metadata 5、写出文件系统 5.1 创建分区表 5.2 滚动策略、文件合并、分区提交 5.3 指定 Sink Parallelism 6、示例_通过FlinkSQL读取kafk…...

call函数和apply函数的区别

call和apply是 JavaScript 中的两个函数方法&#xff0c;用于调用函数并指定函数内部的this值以及传递参数。它们的主要区别在于参数的传递方式。 call方法&#xff1a;call方法允许你在调用函数时&#xff0c;显式地指定函数内部的this值和参数列表。它的语法为&#xff1a; …...

JavaCV踩坑之路1——Mac上安装OpenCV

Mac无法安装opencv 更新Homebrew&#xff1a; 打开终端并运行以下命令来更新Homebrew&#xff1a; brew update 移除Taps&#xff08;仓库&#xff09;: 可能与homebrew-services仓库有关。你可以尝试将它移除&#xff1a; brew untap homebrew/services重新安装OpenCV: 在移除…...

es6(三)——常用es6(函数、数组、对象的扩展)

ES6的系列文章目录 第一章 Python 机器学习入门之pandas的使用 文章目录 ES6的系列文章目录0、数值的扩展一、函数的扩展1、函数的默认值2、函数的reset参数 二、数组的扩展1. 将对象转成数组的Array.from()2. 将对象转成数组的Array.from()3. 实例方法 find()&#xff0c;fin…...

API网关与社保模块

API网关与社保模块 理解zuul网关的作用完成zuul网关的搭建 实现社保模块的代码开发 zuul网关 在学习完前面的知识后&#xff0c;微服务架构已经初具雏形。但还有一些问题&#xff1a;不同的微服务一般会有不同的网 络地址&#xff0c;客户端在访问这些微服务时必须记住几十甚至…...

linux 安装 docker

linux 安装 docker docker及版本一键安装docker(本人使用的是手动安装)Docker手动安装 docker及版本 Docker从17.03版本之后分为CE&#xff08;Community Edition: 社区版&#xff09;和EE&#xff08;Enterprise Edition: 企业版&#xff09;。相对于社区版本&#xff0c;企业…...

整数转罗马数字

题目&#xff1a; 罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 …...

利用爬虫采集音频信息完整代码示例

以下是一个使用WWW::RobotRules和duoip.cn/get_proxy的Perl下载器程序&#xff1a; #!/usr/bin/perluse strict; use warnings; use WWW::RobotRules; use LWP::UserAgent; use HTTP::Request; use HTTP::Response;# 创建一个UserAgent对象 my $ua LWP::UserAgent->new();#…...

WebSocket: 实时通信的新维度

介绍&#xff1a; 在现代Web应用程序中&#xff0c;实时通信对于提供即时更新和交互性至关重要。传统的HTTP协议虽然适合请求-响应模式&#xff0c;但对于需要频繁数据交换的场景并不理想。而WebSocket技术的出现填补了这个空白&#xff0c;为Web开发者们带来了一种高效、实时的…...

postgresql(openGauss)模糊匹配参数

被pg系这个show要求精准匹配参数恶心的不轻。 原理是用.psqlrc&#xff08;openGauss用.gsqlrc&#xff09;文件set一个select常量进去&#xff0c;需要用&#xff1a;调用这个常量。理论上也可以增强其他的各种功能。 我在openGauss做的一个例子 .gsqlrc&#xff08;.psqlrc…...

jdk 加密 aes jar包解决

JDK1.8.0_151的无限制强度加密策略文件变动 JDK1.8.0_151无需去官网下载 local_policy.jar US_export_policy.jar这个jar包&#xff0c;只需要修改Java\jdk1.8.0_151\jre\lib\security这目录下的java.security文件配置即可。 随着越来越多的第三方工具只支持 JDK8&#xff0c…...

C++ Primer 第十一章 关联容器 重点解读

1 map自定义排序 #include <map> #include <iostream> #include <functional> using namespace std; int main() {function<bool(pair<int, int>, pair<int, int>)> cmp [&](pair<int, int> p1, pair<int, int> p2) -&g…...

MySQL 8 - 能够成功创建其他用户但无法修改 root 用户的密码

问题&#xff1a; 创建其他用户就可以&#xff0c;为什么修改root 密码不可以&#xff1f; 如果能够成功创建其他用户但无法修改 root 用户的密码&#xff0c;这可能是因为 MySQL 8 及更高版本引入了一个名为"caching_sha2_password"的身份验证插件作为默认设置&…...

k8s kubernetes 1.23.6 + flannel公网环境安装

准备环境&#xff0c;必须是同一个云服务厂商&#xff0c;如&#xff1a;华为&#xff0c;阿里、腾讯等&#xff0c;不要存在跨平台安装K8S&#xff0c;跨平台安装需要处理网络隧道才能实现所有节点在一个网络集群中&#xff0c;这里推荐使用同一家云服务厂商安装即可 这里使用…...

博客系统中的加盐算法

目录 一、为什么要对密码进行加盐加密&#xff1f; 1、明文 2、传统的 MD5 二、加盐加密 1、加盐算法实现思路 2、加盐算法解密思路 3、加盐算法代码实现 三、使用 Spring Security 加盐 1、引入 Spring Security 框架 2、排除 Spring Security 的自动加载 3、调用 S…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

鸿蒙(HarmonyOS5)实现跳一跳小游戏

下面我将介绍如何使用鸿蒙的ArkUI框架&#xff0c;实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...