浅谈Java中的观察者模式

观察者模式是软件开发中常用的一种设计模式,它通过定义一对多的依赖关系,使得一个对象(主题)的状态变化可以通知多个其他对象(观察者)。

这种模式的优点是解耦和增加扩展性,用于实现对象之间的松耦合通信。

如果要自己编码实现,我们通常定义一个主题接口(Subject)和一个观察者接口(Observer)。主题接口中包含注册观察者、移除观察者和通知观察者的方法,而观察者接口中则定义了更新状态的方法。具体的主题类和观察者类实现这些接口,并进行相应的业务逻辑实现。

考虑到实现简单点,我们假定有一个广播类,这个广播类实际上就是一个主题Subject,有多个听众收听这个广播,这里每个听众就是一个观察者Observer

定义一个主题Subject的接口类

/**
 * 主题,被观察者
 */
public interface Subject {

  /**
   * 添加观察者
   */
  void addObserver(Observer observer);

  /**
   * 移除观察者
   */
  void removeObserver(Observer observer);

  /**
   * 通知观察者
   */
  void notifyObserver(String message);
}

定义一个观察者Observer的接口类

/**
 * 观察者
 */
public interface Observer {

  void recieve(String message);

}

接下来,就是定义一个广播的类,用来实现主题接口 

/**
 * 广播,负责向听众广播消息
 */
public class Broadcast implements Subject{

  private final List<Observer> observerList = new ArrayList<>();

  @Override
  public void addObserver(Observer observer) {
    observerList.add(observer);
  }

  @Override
  public void removeObserver(Observer observer) {
    observerList.remove(observer);
  }

  @Override
  public void notifyObserver(String message) {
    for (Observer observer : observerList) {
      observer.recieve(message);
    }
  }
}

再定义一个听众类,用来实现观察者接口

public class Audience implements Observer {

  private final String name;

  public Audience(String name) {
    this.name = name;
  }

  @Override
  public void recieve(String message) {
    System.out.println(name + " received message: " + message);
  }
}

 写一个测试类来测试结果

public class Test {

  public static void main(String[] args) {
    Broadcast broadcast = new Broadcast();

    Audience audience1 = new Audience("哈尔滨听众");
    Audience audience2 = new Audience("大庆听众");

    broadcast.addObserver(audience1);
    broadcast.addObserver(audience2);

    broadcast.notifyObserver("中央电视台黑龙江电视台");
    broadcast.notifyObserver("黑龙江电视台中央电视台");

    broadcast.removeObserver(audience2);

    broadcast.notifyObserver("大庆听众关了广播");
  }

}

结果打印如下 

解释一下,广播了两拨消息,2名听众都收到了这两拨消息。后面移除了一个听众,广播了第三波消息,这时,只有剩下的那个听众收到了广播消息

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode刷题笔记--Hot31-40

1--颜色分类&#xff08;75&#xff09; 主要思路&#xff1a; 快排 #include <iostream> #include <vector>class Solution { public:void sortColors(std::vector<int>& nums) {quicksort(nums, 0, nums.size()-1);}void quicksort(std::vector<int…

软件工程(九) UML顺序-活动-状态-通信图

顺序图和后面的一些图,要求没有用例图和类图那么高,但仍然是比较重要的,我们也需要按程度去了解。 1、顺序图 顺序图(sequence diagram, 顺序图),顺序图是一种交互图(interaction diagram),它强调的是对象之间消息发送的顺序,同时显示对象之间的交互。 下面以一个简…

WebSocket- 前端篇

官网代码 // 为了浏览器兼容websocketconst WebSocket window.WebSocket || window.MozWebSocket// 创建连接 this.socket new WebSocket(ws://xxx)// 连接成功this.socket.onopen (res)>{console.log(websocket 连接成功)this.socket.send(入参字段) // 传递的参数字段}…

软件工程(二十) 系统运行与软件维护

1、系统转换计划 1.1、遗留系统的演化策略 时至今日,你想去开发一个系统,想完全不涉及到已有的系统,基本是不可能的事情。但是对于已有系统我们有一个策略。 比如我们是淘汰掉已有系统,还是继承已有系统,或者集成已有系统,或者改造遗留的系统呢,都是不同的策略。 技术…

使用vlc在线播放rtsp视频url

1. 2. 3. 工具链接&#xff1a; https://download.csdn.net/download/qq_43560721/88249440

云计算——虚拟化中的网络架构与虚拟网络(文末送书)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号&#xff1a;网络豆 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a; 网络豆的主页​​​​​ 目录 前期回顾 前言 一.网卡虚拟化 1.网卡虚拟化方法&…

拆解即时通讯行销,如何提升讯息开启率达300%?

图片来源&#xff1a;SaleSmartly官网 科技日新月异&#xff0c;今时今日商家均转战网络世界&#xff0c;开设网店售卖产品或服务&#xff0c;不少人都会转用即时通讯&#xff08;Instant Messaging&#xff0c;简称IM&#xff09;软件来和客户联络和宣传&#xff0c;因为即时通…

iTween安装

1. 找到Package Manager面板&#xff0c;Packages选择MyAssets-右上角搜索iTween-找到后点DownLoad-点Import 导入 2. 导入后Assets面板结构如下图。 3. 编译器中输入iTween有提示&#xff0c;安装成功。

DevOps系列文章之 Python基础

列表 Python中的列表类似于C语言中的数组的概念&#xff0c;列表由内部的元素组成&#xff0c;元素可以是任何对象 Python中的列表是可变的 简单的理解就是&#xff1a;被初始化的列表&#xff0c;可以通过列表的API接口对列表的元素进行增删改查 1、定义列表 1.可以将列表当成…

图论算法基础:单源最短路径Dijkstra算法分析

文章目录 图的邻接矩阵 一.Dijkstra算法分析算法的核心逻辑要素算法的执行逻辑 二.Dijkstra算法接口实现邻接矩阵堆优化版本: 图的邻接矩阵 namespace Graph_Structure {//Vertex是代表顶点的数据类型,Weight是边的权值的数据类型,MAX_W是权值的上限值(表示不相两)//Direction…

bpmnjs Properties-panel拓展(属性设置篇)

最近有思考工作流相关的事情&#xff0c;绘制bpmn图的工具认可度比较高的就是bpmn.js了&#xff0c;是一个基于node.js的流程图绘制框架。初始的框架只实现了基本的可视化&#xff0c;想在xml进行客制化操作的话需要拓展&#xff0c;简单记录下几个需求的实现过程。 修改基础 …

ZLMediaKit 重建docker包

1.下载容器到本地服务器并运行 #此镜像为github持续集成自动编译推送&#xff0c;跟代码(master分支)保持最新状态 docker run -id -p 1935:1935 -p 8080:80 -p 8443:443 -p 8554:554 -p 10000:10000 -p 10000:10000/udp -p 8000:8000/udp -p 9000:9000/udp zlmediakit/zlmedi…

第六章:数据结构与算法-par1:典型数据结构

文章目录 一、典型数据结构介绍1.1 基本概念和术语1、基本数据概念2、抽象数据类型3、算法4、算法复杂度5、数据结构 二、数据的存储结构2.1 线性结构1、线性表&#xff08;一般线性表&#xff09;2、栈和队列&#xff08;受限线性表&#xff09;1) 栈 Stack2&#xff09; 队列…

Linux下套接字TCP实现网络通信

Linux下套接字TCP实现网络通信 文章目录 Linux下套接字TCP实现网络通信1.引言2.具体实现2.1接口介绍1.socket()2.bind()3.listen()4.accept()5.connect() 2.2 服务器端server.hpp2.3服务端server.cc2.4客户端client.cc 1.引言 ​ 套接字(Socket)是计算机网络中实现网络通信的一…

ATA-2161高压放大器的电子实验案例(案例合集)

ATA-2161是一款理想的可放大交直流信号的单通道高压放大器。最大差分输出1600Vp-p(800Vp)高压&#xff0c;可以驱动高压型负载。凭借其优异的指标参数受到不少电子工程师的喜欢&#xff0c;其在电子实验中的应用也非常频繁&#xff0c;下面为大家整理出ATA-2161高压放大器的应用…

Android全面屏下,默认不会全屏显示,屏幕底部会留黑问题

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 公司以前的老项目&#xff0c;便出现了这种情况&#xff0c;网上搜索了各种资料&#xf…

LVS集群 (四十四)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、集群概述 1. 负载均衡技术类型 2. 负载均衡实现方式 二、LVS结构 三、LVS工作模式 四、LVS负载均衡算法 1. 静态负载均衡 2. 动态负载均衡 五、ipvsadm命令详…

docker高级(redis集群三主三从)

1. 新建6个docker容器redis实例 docker run -d --name redis-node-1 --net host --privilegedtrue -v /redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381docker run -d --name redis-node-2 --net host --privilegedtrue -v /…

Matlab图像处理-平移运算

几何运算 几何运算又称为几何变换&#xff0c;是将一幅图像中的坐标映射到另外一幅图像中的新坐标位置&#xff0c;它不改变图像的像素值&#xff0c;只是改变像素所在的几何位置&#xff0c;使原始图像按照需要产生位置、形状和大小的变化。 图像几何运算的一般定义为&#…

STM32使用PID调速

STM32使用PID调速 PID原理 PID算法是一种闭环控制系统中常用的算法&#xff0c;它结合了比例&#xff08;P&#xff09;、积分&#xff08;I&#xff09;和微分&#xff08;D&#xff09;三个环节&#xff0c;以实现对系统的控制。它的目的是使 控制系统的输出值尽可能接近预…