java 观察者模式示例_Java中的观察者设计模式-示例教程

java 观察者模式示例

观察者模式行为设计模式之一 。 当您对对象的状态感兴趣并希望在发生任何更改时得到通知时,观察者设计模式很有用。 在观察者模式中,监视另一个对象状态的对象称为Observer ,而正在监视的对象称为Subject 。 根据GoF,观察者模式意图是:

在对象之间定义一对多依赖关系,以便当一个对象更改状态时,将自动通知和更新其所有依赖关系。

主题包含观察者列表,以通知其状态的任何更改,因此它应提供观察者可以自己注册和注销的方法。 主题还包含一种将所有更改通知所有观察者的方法,它既可以在通知观察者的同时发送更新,也可以提供另一种获取更新的方法。

观察者应该有一个方法来设置要监视的对象,另一种方法将由Subject用来通知他们任何更新。

Java提供了一个内置平台,用于通过java.util.Observable类和java.util.Observer接口实现Observer模式。 但是由于它的实现非常简单,因此并未得到广泛使用,并且大多数时候我们不想只为了实现Observer模式而扩展一个类,因为Java在类中没有提供多重继承。

Java消息服务(JMS)使用Observer模式Mediator模式来允许应用程序向其他应用程序订阅和发布数据。

模型-视图-控制器(MVC)框架还使用观察者模式,其中模型是主题,视图是观察者,可以注册以获取有关模型的任何更改的通知。

观察者模式示例

对于我们的示例,我们将实现一个简单的主题,观察者可以注册该主题。 每当将任何新消息发布到该主题时,所有注册观察者都会收到通知,他们可以使用该消息。

根据主题的要求,这里是基本主题接口,用于定义任何具体主题要实施的合同方法。

package com.journaldev.design.observer;public interface Subject {//methods to register and unregister observerspublic void register(Observer obj);public void unregister(Observer obj);//method to notify observers of changepublic void notifyObservers();//method to get updates from subjectpublic Object getUpdate(Observer obj);}

接下来,我们将为Observer创建合同,将有一种方法将Subject附加到观察者,另一种方法供Subject用来通知任何更改。

package com.journaldev.design.observer;public interface Observer {//method to update the observer, used by subjectpublic void update();//attach with subject to observepublic void setSubject(Subject sub);
}

现在我们的合同已经准备好了,让我们继续本主题的具体实施。

package com.journaldev.design.observer;import java.util.ArrayList;
import java.util.List;public class MyTopic implements Subject {private List<Observer> observers;private String message;private boolean changed;private final Object MUTEX= new Object();public MyTopic(){this.observers=new ArrayList<>();}@Overridepublic void register(Observer obj) {if(obj == null) throw new NullPointerException("Null Observer");if(!observers.contains(obj)) observers.add(obj);}@Overridepublic void unregister(Observer obj) {observers.remove(obj);}@Overridepublic void notifyObservers() {List<Observer> observersLocal = null;//synchronization is used to make sure any observer registered after message is received is not notifiedsynchronized (MUTEX) {if (!changed)return;observersLocal = new ArrayList<>(this.observers);this.changed=false;}for (Observer obj : observersLocal) {obj.update();}}@Overridepublic Object getUpdate(Observer obj) {return this.message;}//method to post message to the topicpublic void postMessage(String msg){System.out.println("Message Posted to Topic:"+msg);this.message=msg;this.changed=true;notifyObservers();}}

注册和注销观察者的方法实现非常简单,额外的方法是postMessage() ,客户端应用程序将使用该方法将String消息发布到主题。 请注意,布尔变量可跟踪主题状态的变化,并用于通知观察者。 此变量是必需的,这样,如果没有更新,并且有人调用notifyObservers()方法,它就不会向观察者发送错误的通知。

还请注意,在notifyObservers()方法中使用了同步 ,以确保仅将消息发送给在将消息发布到主题之前注册的观察者。

这是将监视该主题的Observers的实现。

package com.journaldev.design.observer;public class MyTopicSubscriber implements Observer {private String name;private Subject topic;public MyTopicSubscriber(String nm){this.name=nm;}@Overridepublic void update() {String msg = (String) topic.getUpdate(this);if(msg == null){System.out.println(name+":: No new message");}elseSystem.out.println(name+":: Consuming message::"+msg);}@Overridepublic void setSubject(Subject sub) {this.topic=sub;}}

注意, update()方法的实现是在调用Subject getUpdate()方法来获取消息时使用的。 我们可以通过将message作为参数传递给update()方法来避免此调用。

这是使用我们的主题实现的简单测试程序。

package com.journaldev.design.observer;public class ObserverPatternTest {public static void main(String[] args) {//create subjectMyTopic topic = new MyTopic();//create observersObserver obj1 = new MyTopicSubscriber("Obj1");Observer obj2 = new MyTopicSubscriber("Obj2");Observer obj3 = new MyTopicSubscriber("Obj3");//register observers to the subjecttopic.register(obj1);topic.register(obj2);topic.register(obj3);//attach observer to subjectobj1.setSubject(topic);obj2.setSubject(topic);obj3.setSubject(topic);//check if any update is availableobj1.update();//now send message to subjecttopic.postMessage("New Message");}}

当我们运行上面的程序时,我们得到以下输出。

Obj1:: No new message
Message Posted to Topic:New Message
Obj1:: Consuming message::New Message
Obj2:: Consuming message::New Message
Obj3:: Consuming message::New Message

观察者模式类图

观察者模式

观察者模式也称为发布-订阅模式。 它的一些实现是;

  • Swing中的java.util.EventListener
  • javax.servlet.http.HttpSessionBindingListener
  • javax.servlet.http.HttpSessionAttributeListener

这就是Java中Observer模式的全部内容,希望您喜欢它。 通过评论和与他人分享来分享您的爱。

参考: Java的观察者设计模式- 开发者食谱博客上的JCG合作伙伴 Pankaj Kumar的示例教程 。

翻译自: https://www.javacodegeeks.com/2013/08/observer-design-pattern-in-java-example-tutorial.html

java 观察者模式示例

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

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

相关文章

电磁场与电磁波实验一 熟悉Matlab软件在电磁场领域的应用

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送&#xff1a;matlab电磁…

高斯信道下基带模型的多用户BPSK直接序列扩频系统MATLAB仿真(m序列、Gold序列和正交Gold序列)(代码见CSDN同名资源,博客中也有代码)

关注公号【逆向通信猿】更精彩!!! 一、伪随机序列PN码的生成 伪随机序列有很多种,如m序列、Gold序列和正交Gold序列,其中m序列的构造及MATLAB生成方法见: 线性移位寄存器序列(m序列)之MATLAB实现 m序列虽然性能优良,但同样长度的m序列个数不多,且m序列之间的互相…

信号处理系统综合设计-求解器函数的设计(连续和离散时间系统)

微信公众号&#xff1a;创享日记 发送&#xff1a;求解器 获取完整报告&#xff08;含源程序代码结果分析&#xff09; 一、在s域分析连续时间系统的方法 一个线性时不变连续时间系统可以用线性常系数微分方程描述&#xff0c;对系统的时域分析可归结为利用数学方法对该方程求解…

OFFICE2019精简安装D盘(包括Word、PPT、Excel,可根据需要调整)+VISIO2019+Mathtype7.4.0完美下载安装教程

经过笔者测试&#xff0c;64位的OFFICE2019、VISIO2019对MathType兼容性很差&#xff0c;时不时出现问题&#xff0c;且网上能查阅到的解决办法均不能很好地解决。 无奈之下换回32位的OFFICE2019&#xff0c;配合MathType7.4.0&#xff0c;简直完美&#xff0c;现将OFFICE 201…

仿知乎论坛社区社交微信小程序

微信公众号&#xff1a;创享日记 发送&#xff1a;仿知乎 获取完整源码&#xff08;静态数据&#xff09;&#xff0c;导入微信开发者工具即可 说明&#xff1a;源码主要是前端&#xff0c;后端可自行开发 1、首页 问题列表 话题列表 触底加载刷新 2、问题列表及回答 3、发现…

商城小程序项目完整源码(微信小程序)

微信公众号&#xff1a;创享日记 发送&#xff1a;碰撞商城 获取完整源码详细注释&#xff08;打开微信开发工具导入即可&#xff09; 1、首页 ①搜索框可以点击搜索 ②轮播图可以点击跳转 ③功能模块可以自行开发 2、搜索 输入关键词会有推荐列表 UI可以自行设计得更漂亮 3、…

java 设计模式 示例_Java中的访问者设计模式–示例教程

java 设计模式 示例访客模式是行为设计模式之一 。 当我们必须对一组相似类型的对象执行操作时&#xff0c;将使用访问者模式。 借助访问者模式&#xff0c;我们可以将操作逻辑从对象移动到另一个类。 例如&#xff0c;假设有一个购物车&#xff0c;我们可以在其中添加不同类型…

电商商城小程序项目完整源码(微信小程序)

微信公众号&#xff1a;创享日记 发送&#xff1a;简商城 获取完整源码&#xff08;导入微信开发者工具即可&#xff09; 如果要较完整学习微信小程序云开发可以看看这个“云公开课”帮你了解完整的微信云托管部署流程&#xff0c;学习实战级的小程序开发。 1、首页 点击轮播图…

汉字查拼音微信小程序项目源码

微信公众号&#xff1a;创享日记 发送&#xff1a;查拼音 获取完整源码&#xff08;微信开发者工具导入即可用&#xff09; ①基本包括全部汉字 ②支持多音字 "治":["zh","ch"],"沺":["tin"],"油":["yu"…

高斯信道、单径Rayleigh信道和多径衰落信道下基带模型的多用户BFSK直接序列扩频系统MATLAB仿真(m序列、Gold序列和正交Gold序列)

结果预览 高斯 BFSK调制方式在采用m序列时,在高斯信道下的性能仿真结果如下: BFSK调制方式在采用正交Gold序列时,在高斯信道下的性能仿真结果如下: 单径Rayleigh 采用m序列时,在单径Rayleigh信道下的性能仿真结果如下:

随机抽奖转盘微信小程序项目源码

微信小程序&#xff1a;创享日记 发送&#xff1a;抽奖转盘 获取完整源码&#xff08;微信开发者工具打开即可用&#xff09; 可以容易自行修改&#xff0c;融入自己的项目里面。 function formatTime(date) {var year date.getFullYear()var month date.getMonth() 1var d…

简易计算器微信小程序项目源码

微信公众号&#xff1a;创享日记 发送&#xff1a;计算器 获取完整源码&#xff08;微信开发者工具导入即可用&#xff09; 以下可以忽略不看&#xff01; 微信小程序&#xff0c;小程序的一种&#xff0c;英文名Wechat Mini Program&#xff0c;是一种不需要下载安装即可使用…

MongoDB初学者教程

1. MongoDB简介 在本文中&#xff0c;我们提供了全面的MongoDB教程&#xff0c;该教程与基于Java的应用程序集成。 每当我们读到NoSQL数据库时&#xff0c;我们都需要知道为什么在SQL数据库运行良好时会开发它们。 NoSQL的基础是通过宽松的ACID &#xff08;原子性&#xff0c;…

手势密码解锁微信小程序项目源码

微信公众号&#xff1a;创享日记 发送&#xff1a;手势密码 获取完整源码&#xff08;导入微信开发者工具即可用&#xff09; 以下可以忽略不看&#xff01; 手势密码就是在手机触屏上设置一笔连成的九宫格图案&#xff0c;登录时画一下设定的图形。 运行程序&#xff0c;发…

带你一步一步实战分析缓冲区溢出漏洞攻击

关注公众号有惊喜【部分付费文章免费阅读&#xff0c;持续更新中…】 点击公众号底部【逆向杂记】可见 文件1 (A)描述此二进制文件提供的服务&#xff0c;不需要运行二进制文件来找出这一点。 (B)有可能对此二进制文件进行缓冲区溢出攻击&#xff0c;它在哪里&#xff1f;哪些…

【JavaSE】Java进阶知识一(泛型详解,包括泛型方法,协变,逆变,擦除机制)

目录 泛型 1. 什么是泛型 2.泛型方法 3.通配符上界&#xff08;泛型的协变&#xff09; 4.通配符下界&#xff08;泛型的逆变&#xff09; 5.泛型的编译&#xff08;擦除机制&#xff09; 泛型 泛型&#xff1a;就是让一个类能适用于多个类型&#xff0c;就是在封装数据结…

Python实验三:Python程序设计之组合数据类型

微信公众号&#xff1a;创享日记 发送&#xff1a;python实验 获取完整清晰报告和源码以及其它资源 前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习…

Python爬虫和数据分析,石油原油加工产品产量数据处理分析

前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送&#xff1a;原油分析 获取完整无水印报告P…

Python实验二:Python程序设计之结构与复用

微信公众号&#xff1a;创享日记 发送&#xff1a;python实验 获取完整清晰报告和源码以及其它资源 前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习…

基于x86汇编的飞机大战

运行结果 代码 ;宏定义一个显示函数(显示一组字符串) PUTS MACRO STRINGPUSH AXPUSH DXLEA DX, STRING ;LEA将内存地址的