设计模式(16):观察者模式

核心

  • 观察者模式主要用于1:N的通知。当一个对象(目标对象Subject或者Abservable)的状态变化时,他需要及时告知一系列对象(观察者对象,Observer),令 他们做出响应。
  • 通知观察者的方式:
    • 推:
      • 每次都会把通知以广播方式发送给所有观察者,所有观察者只能被动接收。
    • 拉:
      • 观察者只要知道有情况变化即可。至于什么时候获取内容,获取什么内容,都可以自主决定。

观察者模式角色

  • 抽象主题对象(Subject): 聚合所有的观察者,提供注册和移除观察者的方法,并且提供通知所有观察者的方法。
  • 具体的主题对象(ConcreteSubject): 实现抽象主题对象。并提供状态修改方法;
  • 抽象观察者(Observer): 提供更新观察者的方法;
  • 具体观察者(ConcreteObserver): 实现抽象观察者.

场景

  • 聊天室程序的创建。服务器创建好后,A,B,C三个客户端连上来公开聊天。A向服务器发送数据,服务器端聊天数据改变。我们希望将这些聊天数据分别发给其他在线的客户。也就是说,每个客户端需要更新服务端的数据;
  • 网站上,很多人订阅了“java主题“的新闻,当有这个主题新闻时,就会将这些新闻发送给所有订阅的人。
    这些场景,我们都可以使用观察者模式来处理。我们可以把多个订阅者、客户端称之为观察者;需要同步给多个订阅者的数据封装到对象中,称之为目标。

开发中常见的场景

  • 聊天室程序的服务器转发给所有客户端;
  • 网络游戏场景中,服务器将客户端的状态进行分发;
  • 邮件订阅;
  • servlet中监听器的实现;
  • spring项目中的事件监听器的实现;

代码实现

  • 抽象主题对象
/*** 抽象主题对象*/
public abstract class Subject {// 所有的观察者protected List<Observer> list = new ArrayList<Observer>();	public void registerObserver(Observer obs){list.add(obs);}public void removeObserver(Observer obs){list.remove(obs);}//通知所有观察者更新状态public void notifyAllObserver(){for(Observer obs:list){obs.update(this);}}
}
  • 具体主题对象
/*** 具体的主题对象*/
public class ConcreteSubject extends Subject{private int state;public int getState() {return state;}public void setState(int state) {this.state = state;//主题(目标)对象发生变化,请通知所有观察者this.notifyAllObserver();}
}
  • 抽象观察者类
/*** 	抽象观察者*/
public interface Observer {void update(Subject subject);	
}
  • 具体观察者类
/*** 具体观察者A*/
public class AObserver implements Observer{private int state;public int getState() {return state;}public void setState(int state) {this.state = state;}@Overridepublic void update(Subject subject) {this.state=((ConcreteSubject)subject).getState();}
}
/*** 具体观察者B*/
public class BObserver implements Observer{private int state;public int getState() {return state;}public void setState(int state) {this.state = state;}@Overridepublic void update(Subject subject) {this.state=((ConcreteSubject)subject).getState();}
}
  • 客户端调用
public static void main(String[] args) {//目标对象ConcreteSubject subject=new ConcreteSubject();//创建多个观察者AObserver observerA=new AObserver();BObserver observerB=new BObserver();//将观察者添加到subject对象的观察者队伍中subject.registerObserver(observerA);subject.registerObserver(observerB);//改变subject状态之前System.out.println("改变subject状态之前");System.out.println(observerA.getState());System.out.println(observerB.getState());//改变subject状态subject.setState(300);//观察者状态是否发生变换System.out.println("改变subject状态之后");System.out.println(observerA.getState());System.out.println(observerB.getState());
}



更多设计模式学习:

          设计模式(1):介绍
          设计模式(2):单例模式
          设计模式(3):工厂模式
          设计模式(4):建造者模式
          设计模式(5):原型模式
          设计模式(6):桥接模式
          设计模式(7):装饰器模式
          设计模式(8):组合模式
          设计模式(9):外观模式
          设计模式(10):享元模式
          设计模式(11):适配器模式
          设计模式(12):代理模式
          设计模式(13):模板方法模式
          设计模式(14):命令模式
          设计模式(15):迭代器模式
          设计模式持续更新中…

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

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

相关文章

浅谈分布式光伏电站的运维管理

摘要&#xff1a;随着近些年我国对节能降耗关注力度的持续加大&#xff0c;为满足人们不断增长的电能需求&#xff0c;光伏发电产业得到迅猛发展&#xff0c;其中分布式光伏发电的比重持续增长。在打赢脱贫攻坚战的大背景下&#xff0c;国家电网公司探索出一条“阳光扶贫”的扶…

康耐视visionpro-CogPMAlignTool工具详细说明

图案位置搜索工具 可在图像中找到你训练的特征所在的位置等信息 基于边缘特征的模板而不是基于像素的模板匹配&#xff0c;比像素格栅表现更快捷准确支持旋转和缩放 三种主要算法&#xff1a;PatMax&#xff08;精度最高&#xff09;, PatQuick&#xff08;速度最快&#xff0…

Spring Cloud微服务入门(一)

微服务的演变过程 //controller 视图交互层 前端数据处理传给service //1.DAO RequestBody userDAO String id;String type; {"id":"lcs", "type":"lcs"} //2.GET请求 findUserById&#xff1f;id1&typelcsRequestParam String …

ChatGPT新视角:发现学术论文写作的创新可能性

ChatGPT无限次数:点击直达 ChatGPT新视角&#xff1a;发现学术论文写作的创新可能性 在当今信息爆炸的时代&#xff0c;学术研究和论文写作变得愈发重要。然而&#xff0c;传统的写作过程常常耗费大量时间和精力&#xff0c;每篇论文都需要仔细推敲和精心打磨。随着人工智能技…

5.3.1 配置交换机 SSH 管理和端口安全

5.3.1 实验1:配置交换机基本安全和 SSH管理 1、实验目的 通过本实验可以掌握&#xff1a; 交换机基本安全配置。SSH 的工作原理和 SSH服务端和客户端的配置。 2、实验拓扑 交换机基本安全和 SSH管理实验拓扑如图所示。 交换机基本安全和 SSH管理实验拓扑 3、实验步骤 &a…

全面的Docker快速入门教程(详细)

前言&#xff1a; 都2024年了&#xff0c;你还在为了安装一个开发或者部署环境、软件而花费半天的时间吗&#xff1f;你还在解决开发环境能够正常访问&#xff0c;而发布测试环境无法正常访问的问题吗&#xff1f;你还在为持续集成和持续交付&#xff08;CI / CD&#xff09;工…

flink1.18源码本地调试环境

01 源码本地调试环境搭建 1. 从github拉取源码创建本地项⽬ https://github.com/apache/flink.git 可以拉取github上官⽅代码 https://github.com/apache/flink.git GitHub - apache/flink: Apache Flink 2. 配置编译环境 ctrlaltshifts &#xff08;或菜单&#xff09;打…

OpenHarmony Neptune开发板-MQTT连接华为IoT平台

本示例将演示如何在Neptune开发板上使用MQTT协议连接华为IoT平台,使用的是ATH20温湿度传感器模块与Neptune开发板 本示例实现AHT20温湿度数据上报华为IoT平台,IoT平台下发命令控制LED灯的开关 使用W800 SDK功能包中libemqtt来实现连接华为IoT平台 程序设计 初始化 一、MQT…

上位机图像处理和嵌入式模块部署(qmacvisual亮度检测)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说过&#xff0c;在机器视觉当中&#xff0c;对于光源的处理要非常小心。这里面不仅包括了选择什么样的光源&#xff0c;还取决于怎样使用…

二叉树的遍历——洛谷P1364

1. 如何构建父节点与子节点的关系 通过一个结构体&#xff0c;包括每一个节点的父、子节点&#xff0c;在读入一个节点的数据时&#xff0c;标记其子节点的父节点为自己 2. 代码 #include<bits/stdc.h> using namespace std;struct node {int f,l,r,w; }tr[105];int n,s,…

WPF文本框TextEdit不以科学计数法显示

WPF文本框TextEdit不以科学计数法显示 一个float或者double类型的数值&#xff0c;如果小数点后0的个数≥4&#xff0c;在界面上就会自动以科学计数法显示&#xff0c; 比如&#xff1a;0.00003会显示成这样 但是很多时候我并不希望它这样显示&#xff0c;因为这样不方便编辑…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之一 简单视频放大抖动效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之一 简单视频放大抖动效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之一 简单视频放大抖动效果 一、简单介绍 二、简单视频放大抖动效果实现原理 三、简单视频放大…

C# WPF编程-命令

C# WPF编程-命令 概述WPF命令模型ICommand接口RoutedCommand类RoutedUICommand类命令库 概述 使用路由事件可以响应广泛的鼠标和键盘事件&#xff0c;这些事件是低级的元素。在实际应用程序中&#xff0c;功能被划分成一些高级的任务。这些任务可通过各种不同的动作和用户界面…

人大金昌netcore适配,调用oracle模式下存储过程\包,返回参数游标

using KdbndpConnection conn new KdbndpConnection("Host192.168.133.221;Port54321;Databasedb1;Poolingtrue;User IDsystem;Password123");conn.Open();//存储过程调用也是类似using var cmd conn.CreateCommand();cmd.CommandText "模式.包名称.存储过程…

Spring Boot 学习(2)——HelloWorld

HelloWorld&#xff01;全宇宙码农的第一个&#xff08;行&#xff09;程序&#xff08;代码&#xff09;。 1、创建项目 打开idea&#xff0c;新建一个maven项目。 1&#xff09;选择项目sdk&#xff08;本例是1.8&#xff09; 2&#xff09;输入GroupId&#xff08;co…

阿里云服务器租用价格表,100元可以买哪些配置?

2024年阿里云服务器优惠价格表&#xff0c;一张表整理阿里云服务器最新报价&#xff0c;阿里云服务器网aliyunfuwuqi.com整理云服务器ECS和轻量应用服务器详细CPU内存、公网带宽和系统盘详细配置报价单&#xff0c;大家也可以直接移步到阿里云CLUB中心查看 aliyun.club 当前最新…

CEF的了解

(14 封私信 / 80 条消息) CEF和Electron的区别是什么&#xff1f; - 知乎 (zhihu.com) Electron面向的开发者&#xff1a;会用JavaScript,HTML,CSS&#xff0c;不会C CEF面向的开发者&#xff1a;会用JavaScript,HTML,CSS&#xff0c;会C (14 封私信 / 80 条消息) liulun - …

认识什么是Git

目录 1. 认识Git 1.1. 问题引入 1.2. 概念 1.3. 作用 1.4. 如何学 1.5. Git 安装 1.6. Git配置用户信息 2. Git仓库 2.1. Git 仓库&#xff08;repository&#xff09; 2.2. 创建 2.3. 需求 3. Git的三个区域 3.1. Git 使用时的三个区域 3.2. 工作区的内容&#…

怎么快速上手虚拟化(容器)技术——以 Docker 为例

Docker 整体介绍 Docker 是一种使用 Go 语言开发的容器工具。所谓容器&#xff0c;实际上是一种虚拟化技术&#xff0c;用于为应用提供虚拟化的运行环境&#xff0c;相较于虚拟机具有轻量级、低延迟的特性。 下面是对上述介绍的说明&#xff1a; 应用程序运行需要一定的依赖…

【Python整理】 Python知识点复习

1.Python中__init__()中声明变量必须都是self吗? 在Python中的类定义里&#xff0c;init() 方法是一个特殊的方法&#xff0c;称为类的构造器。在这个方法中&#xff0c;通常会初始化那些需要随着对象实例化而存在的实例变量。使用 self 是一种约定俗成的方式来引用实例本身。…