当前位置: 首页 > 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…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...