Java设计模式:观察者模式

article/2025/9/10 16:43:13

一、什么是观察者模式?

       又叫做发布-订阅模式,定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。UML结构图如下:

 其中涉及到四种角色:

1.抽象目标(或抽象主题,抽象被观察者):提供了用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。

2.具体目标(或具体主题,具体被观察者):继承Subject类,在这里实现具体业务。
3.抽象观察者:一般是一个抽象类或接口,它包含了一个更新的方法,当接到具体主题的更改通知时被调用。
4.具体观察者:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。

二、使用观察者模式的场景和优缺点

1.场景

  • 关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系。
  • 事件多级触发场景。
  • 跨系统的消息交换场景,如消息队列、事件总线的处理机制。

2.优点

 解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变换都不会影响另一边的变换。

3.缺点

(1)在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。

(2)如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。

(3)如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。

(4)虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。

三、观察者模式的代码样例

1.抽象目标:Subject 

abstract class Subject {//容器protected List<Observer> observers = new ArrayList<Observer>();//增加观察者方法public void add(Observer observer) {observers.add(observer);}//删除观察者方法public void remove(Observer observer) {observers.remove(observer);}//通知观察者方法public abstract void notifyObserver();
}

2、具体目标:ConcreteSubject 

public class ConcreteSubject extends Subject {@Overridepublic void notifyObserver() {System.out.println("具体目标发生改变...");for (Object obs : observers) {((Observer) obs).response();}}
}

3、抽象观察者:Observer 

public interface Observer {void response(); //反应
}

4.具体观察者1:ConcreteObserver1 

public class ConcreteObserver1 implements Observer {@Overridepublic void response() {System.out.println("具体观察者1做出反应");}
}

5.具体观察者2:ConcreteObserver2  

public class ConcreteObserver2  implements  Observer{@Overridepublic void response() {System.out.println("具体观察者2做出反应");}
}

6、主方法测试

public class TestMain {public static void main(String[] args) {Subject subject = new ConcreteSubject();Observer obs1 = new ConcreteObserver1();Observer obs2 = new ConcreteObserver2();subject.add(obs1);subject.add(obs2);subject.notifyObserver();}
}

控制台打印

具体目标发生改变...
具体观察者1做出反应
具体观察者2做出反应

在线举牌照片生成


http://chatgpt.dhexx.cn/article/n5xoqLsg.shtml

相关文章

初探Java设计模式------观察者模式

前言 最近刚开始学习RxJava&#xff0c;众所周知&#xff0c;Rxjava就是扩展的观察者模式&#xff0c;所以想学习Rxjava&#xff0c;先入手了解一下观察者模式是很有必要的。那么今天就先稍微了解一下什么是观察者模式。 定义 观察者(Observer)模式&#xff1a;是对象的行为模…

java设计模式(3)--观察者模式

&#xff08;一&#xff09;观察者模式 观察者模式定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。 该模式有以下角色&#xff1a; &#xff08;1&#xff09;抽象主题&#xff08;Subjec…

Java设计模式之行为型:观察者模式

一、什么是观察者模式&#xff1a; 观察者模式又称为 发布-订阅模式&#xff0c;定义了对象之间一对多依赖关系&#xff0c;当目标对象(被观察者)的状态发生改变时&#xff0c;它的所有依赖者(观察者)都会收到通知。一个观察目标可以对应多个观察者&#xff0c;而这些观察者之间…

java监听设计模式(java观察者设计模式)

今天给大家分享一下观察者设计模式&#xff08;监听设计模式&#xff09;&#xff0c;该模式在很多主流得框架、源码中使用率非常高。在分享之前先给大家讲一个我们使用手机的一个场景&#xff0c;我们都用过手机&#xff0c;当我们手机来电话的时候&#xff0c;会有各种复杂的…

【十一】设计模式~~~结构型模式~~~代理模式(Java)

【学习难度&#xff1a;★★★☆☆&#xff0c;使用频率&#xff1a;★★★★☆】 6.1. 模式动机 在某些情况下&#xff0c;一个客户不想或者不能直接引用一个对 象&#xff0c;此时可以通过一个称之为“代理”的第三者来实现 间接引用。代理对象可以在客户端和目标对象之间起…

JAVA架构之路(设计模式之观察者模式)

设计模式之观察者模式 定义&#xff1a;对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新 核心原理&#xff1a; 1.被观察者中维护一个观察者对象列表 2.观察者可新增可可移除。 需要角色&#…

程序员百宝箱---搭建自己专属的在线工具集

相信各位开发者/程序员在开发过程中都使用过各种在线工具吧。比如 1 校验或格式化 json 字符串 2 使用 base64 的加密解密&#xff0c;url 的编码解码 urlencode、urldecode 等 3 调试正则表达式是否正确 4 时间戳与格式化日期互相转换 5 文本对比&#xff0c;比较两个代码文件…

如何部署JSP应用到阿里云服务器上(一)

今天讲解一下如何部署JSP应用到阿里云服务器上&#xff0c;我使用的后台服务器是 Tomcat服务器&#xff0c;服务器应用的开发语言是 Java Web &#xff0c;后台的数据库使用的是MySQL 1 打开阿里云官方网站 https://www.aliyun.com/?utm_mediumtext&utm_sourcebdbrand&am…

开源项目精选推荐-杨小杰工具箱(YoungxjTools)

演示 预览地址: https://tools.yum6.cn/ 程序介绍 01、首页底部友情链接 02、网站公告页面功能 03、内置留言管理功能 04、后台网站信息设置 05、内置smtp发信配置 06、支持两主题的切换 07、关于页面支持留言, 08、程序已集成32种小工具 更多功能 介绍 请搭建 自行测试

C++构造函数之初始化列表

C构造函数之初始化列表 构造函数可以说是对于C每个类来说最重要的组成部分&#xff0c;之前也详细介绍过构造函数的相关知识&#xff0c;今天给构造函数进行补充&#xff0c;主要说明一下构造函数的初始值列表 一、初始化列表的写法 仍然以之前介绍构造函数时使用的学生类来…

C++初始化列表详解

目录&#xff1a; 定义 使用初始化列表的原因 必须使用初始化列表的时候 成员变量的顺序 定义 与其他函数不同&#xff0c;构造函数除了有名字&#xff0c;参数列表和函数体之外&#xff0c;还可以有初始化列表&#xff0c;初始化列表以冒号…

C++类的初始化列表

意义 初始化列表是类中构造函数的一部分&#xff0c;用于实例化类中变量时 赋初值。 需要先了解 构造函数的基本知识。CSDN-构造函数https://blog.csdn.net/weixin_44212838/article/details/124901019?spm1001.2014.3001.5501 用法 在函数头与函数体之间&#xff0c;用一…

详解初始化列表

初始化列表 定义 构造函数有个特殊的初始化方式叫“初始化表达式表”&#xff08;简称初始化列表&#xff09;。初始化列表位于函数参数表之后&#xff0c;却在函数体 {} 之前。这说明该表里的初始化工作发生在函数体内的任何代码被执行之前。 Date(int year, int month, in…

C++ 成员初始化列表

这里写目录标题 数据成员是某一个类的对象&#xff0c;且这个类没有默认构造函数数据成员的类型是const或者引用子类初始化父类初始化列表先后顺序使用成员初始化列表的优点 在以下三种情况下需要使用初始化成员列表&#xff1a; 需要初始化的数据成员是某一个类的对象&#xf…

【深入理解】初始化列表

目录 一、什么是初始化列表&#xff1f; 二、初始化列表长啥样&#xff1f; 三、初始化列表的特性 1、由于是在定义阶段进行的初始化&#xff0c;所以&#xff0c;只能在定义阶段进行的初始化类型便只能在初始化列表中进行初始化。 2、初始化顺序不是跟着初始化列表走的&#x…

C++ 初始化列表详解

目录 1.什么是初始化列表 2.什么时候需要使用初始化列表&#xff1f; 3.初始化列表的效率 4.初始化列表的初始化顺序 1.什么是初始化列表 class A { public:A(int value):m_dada(value){}private:int m_dada; }; 如上图&#xff0c;红色圈起来的部分&#xff0c;就是构造函…

【C++】-- 初始化列表

目录 一、用初始化列表初始化对象 1.初始化列表用法 2.初始化列表特性 二、explicit关键字 1.内置类型的隐式转换 2.如何避免单参构造函数初始化发生隐式类型转换 三、匿名对象 1.匿名对象定义 2.匿名对象应用场景 创建一个类对象时&#xff0c;编译器通过调用构造函…

字符串逆序(数组倒序输出)

题目信息&#xff1a; 样例输出 copy edcba 新手导读&#xff1a; 题目描述信息&#xff1a;字符串的倒序输出肯定是字符数组的倒序输出&#xff1b; 输入信息&#xff1a;输入条件是最后字符不为回车&#xff1b;所以应该先用变量存入字符进行判断&#xff0c;再使用这个…

C语言实现字符串倒序

C语言显示字符串倒序 倒序字符串的方法很多&#xff0c;这里给出常见的两种 1.倒序字符串指针法 void reverse_string(char *arr) {int len strlen(arr);char* left arr; //指向头部的指针char* right arr (len - 1); //指向尾部的指针char temp;while(left <…

C语言:输入一串字符串,并倒序输出(vs)

一&#xff1a;问题&#xff1a; 输入一串字符串倒序输出 例&#xff1a;输入abcdefg 输出gfedcba 二&#xff1a;思路&#xff1a; &#xff08;1&#xff09;先输入一串字符串&#xff0c;然后利用for语句倒序输出即可&#xff1b; 三&#xff1a;实现过程&#xff1a; …