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

设计模式19——观察者模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。

观察者模式(Observer),又名:发布-订阅模式(publish-subscribe)

是一种行为型模式。因为叫发布-订阅模式更容易理解,所以下面说明时大多情况会使用发布-订阅这个名称。

目录

一、概述

1.1、直观的理解:

1.2、主要角色:

1.3、描述对象之间关系的UML图:

1.4、适用场景:

二、简单举例

2.1、对象之间的关系用UML图表示如下:

2.2、Java代码如下:


一、概述

1、观察者模式定义了一种一对多的依赖关系,让多个观察者(订阅者)对象同时监听某一个主题(发布者)对象。这个主题(发布者)对象在状态发生变化时,会通知所有观察者(订阅者)对象,使它们能够自动更新自己。

1.1、直观的理解

(注:关于发布者何时给订阅者通知更新,这个需要结合实际情况来考虑) 

1.2、主要角色:

  • 发布者(目标主题):发布者的抽象类或接口 + 发布者类
  • 订阅者(观察者):订阅者的抽象类或接口 + 订阅者类

1.3、描述对象之间关系的UML图:

1.4、适用场景:

  • 一个抽象模型有两个方面,其中一个方面依赖另一个方面。可以将它们封装独立出来
  • 对一个对象的改变需要同时改变其他对象
  • 一个对象必须通知其他对象,而且其他对象并不是固定不变的

二、简单举例

假设 客户端 要让 发布者 设置自己的状态为hello,再然后通知 张三 和 李四 这两个 订阅者 。例子简单就不再详细分析了。你可以把这当做一个模板,然后灵活使用:

2.1、对象之间的关系用UML图表示如下:

2.2、Java代码如下:

订阅者的抽象类:

abstract class Subscriber {public abstract void update();//接收发布者的消息
}

发布者的抽象类:

abstract class Publisher {private List<Subscriber> list; //链表public Publisher() {//初始化this.list = new LinkedList<>();}public void attach(Subscriber subscriber) { //增加订阅者list.add(subscriber);}public void detach(Subscriber subscriber) {//删除订阅者list.remove(subscriber);}public void notifySubscriber() {//通知订阅者for (Subscriber subscriber : list) {subscriber.update();}}private String publisherState;//发布者状态public String getPublisherState() {//得到发布者状态return this.publisherState;}public void setPublisherState(String publisherState) {//设置发布者状态this.publisherState = publisherState;}
}

具体的发布者A:

public class ConcretePublisherA extends Publisher{//发布者的其它方法
}

具体的订阅者1:

public class ConcreteSubscriber1 extends Subscriber {private String name;//订阅者名称private Publisher publisher;//发布者public ConcreteSubscriber1(String name, Publisher publisher) {//初始化this.name = name;this.publisher = publisher;}@Overridepublic void update() {//接收发布者的消息System.out.println("订阅者是:" + this.name + ",发布者的状态为:" + this.publisher.getPublisherState());}
}

主程序(发起请求的类):

public class Main {public static void main(String[] args) {Publisher publisher = new ConcretePublisherA();Subscriber subscriber1 = new ConcreteSubscriber1("张三", publisher);Subscriber subscriber2 = new ConcreteSubscriber1("李四", publisher);publisher.attach(subscriber1);publisher.attach(subscriber2);publisher.setPublisherState("hello!");//通知订阅者publisher.notifySubscriber();}
}

这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。

如果觉得本文还不错,就请点个赞给作者一点鼓励吧!如果有建议,也请评论指教和讨论!

相关文章:

  • EXCEL VBA终极提速,超级公式,算法优化
  • Oracle EBS API创建AP发票报错:ZX_TAX_STATUS_NOT_EFFECTIVE和ZX_REGIME_NOT_EFF_IN_SUBSCR-
  • AIGC(人工智能生成内容)行业现在适合进入吗
  • ARM鲲鹏920-oe2309-caffe
  • 多模态中的模态有哪些
  • c# mysql 加锁解锁
  • HBase分布式数据库入门到精通
  • Spring MVC+mybatis 项目入门:旅游网(二) dispatcher与controller与Spring MVC
  • 豆瓣电影后端设计
  • 四川汇聚荣聚荣科技有限公司好不好?
  • 六(1)、RTKLIB源码解析 — rnx2rtkp.c
  • 全球首个AI代理驱动的元宇宙生态Wondra,让Web3再次伟大
  • AI生成视频解决方案,降低成本,提高效率
  • 第四十一天 | 62.不同路径 63.不同路径|| 343.整数拆分 96.不同的二叉搜索树
  • 算法打卡 Day13(栈与队列)-滑动窗口最大值 + 前 K 个高频元素 + 总结
  • 分享的文章《人生如棋》
  • conda常用的命令
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • java小心机(3)| 浅析finalize()
  • Laravel 菜鸟晋级之路
  • React16时代,该用什么姿势写 React ?
  • vue-loader 源码解析系列之 selector
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • win10下安装mysql5.7
  • 工程优化暨babel升级小记
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 怎样选择前端框架
  • linux 淘宝开源监控工具tsar
  • Mac 上flink的安装与启动
  • ​iOS安全加固方法及实现
  • ​力扣解法汇总946-验证栈序列
  • #define 用法
  • $.ajax()参数及用法
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (ibm)Java 语言的 XPath API
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (算法)求1到1亿间的质数或素数
  • (杂交版)植物大战僵尸
  • (转)Mysql的优化设置
  • (转)拼包函数及网络封包的异常处理(含代码)
  • (自适应手机端)响应式服装服饰外贸企业网站模板
  • **CI中自动类加载的用法总结
  • ./和../以及/和~之间的区别
  • .NET Framework杂记
  • .net wcf memory gates checking failed
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET应用UI框架DevExpress XAF v24.1 - 可用性进一步增强
  • @Bean有哪些属性
  • [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
  • []新浪博客如何插入代码(其他博客应该也可以)
  • [20160902]rm -rf的惨案.txt