Java设计模式-观察者模式

【Java设计模式】Java设计模式之(九)观察者模式(Observer Pattern) 观察者模式属于行为型模式。 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。 观察者一般可以看做是第三者,举例说明: (1)比如在学校上自习的时候,大家肯定都有过交头接耳、各种玩耍的经历,这时总会有一个“放风”的小伙伴,当老师即将出现时及时“通知”大家老师来了。 (2)比如,拍卖会的时候,大家相互叫价,拍卖师会观察最高标价,然后通知给其它竞价者竞价,这就是一个观察者模式。 (3)对于观察者模式而言,肯定有观察者和被观察者 阅读详情

观察者模式

一、现实生活中的实例

  早上起床,推开窗,看到漫天雪花,我们知道天气降温并下着大雪,于是我们穿上棉服打着雨伞出门;在过马路的时候,看到了红灯,
于是我们停下脚步等着绿灯;当穿过马路,走到公交站台看到公交车刚刚走远,于是我们摆手拦下一辆出租车坐上去上班。

  从天气变化来选择出门的穿着,从交通灯的颜色变化来选择停留,从公交车远走来重新选择车子,我们总是观察者事物的变化来改变
我们的动作。

二、软件设计

  从生活中的启发,我们把通过观察事物的变化来改变另一事物的行为演变成为了一种新的设计模式—观察者模式。

观察者模式的模式动机是建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。

  在此,发生改变的对象称为观察目标,而被通知的对象称为观察者。

  从实例中思考也可知道,多个观察者可以观察同一个对象,而且这些观察者之间没有相互联系。比如,开车的人、汽车的人、走路的
人都在看交通灯,并且都各自根据交通灯的变化而进行各自的动作。

观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

  观察者模式,是一种对象行为型模式;一个观察对象的变化,其相关依赖的N个观察者都会被通知并发生相应的变化。

三、Java中的观察者模式

  Java是面向对象的编程,Java在java.util中提供了Observer接口和Observable类。

3.1、Observer
/**
 * A class can implement the <code>Observer</code> interface when it
 * wants to be informed of changes in observable objects.
 */
public interface Observer {
    /**
     * This method is called whenever the observed object is changed. An
     * application calls an <tt>Observable</tt> object's
     * <code>notifyObservers</code> method to have all the object's
     * observers notified of the change.
     *
     * @param   o     the observable object.
     * @param   arg   an argument passed to the <code>notifyObservers</code>
     *                 method.
     */
    void update(Observable o, Object arg);
}

  该接口约定了观察者的行为,所有观察者需要在被观察目标发生变化时做出相应的响应,具体的就是实现Observer接口的update()方法。

  使用观察者模式,需要有调用者(主要应该是具体的业务类)、观察者、观察目标。

  当前的Observer接口是观察者,观察者要观察观察的目标,目标变化时调用更新方法,因此update()方法参数需要传入具体的观察目标Observable的对象引用。

  调用者如何传递数据给观察者呢?当然是调用观察目标的notifyObservers(Object arg)方法传入数据,把数据再通过观察者的update(Observable o, Object arg)的
方法把数据传递给观察者,这样就实现了调用者与观察者的通信。换句话说:就是通过Observer的update(Observable o, Object arg)方法,把调用者、观察目标、观察者进行关联和通信。

3.1、Observable

  此类表示可观察对象或模型视图范例中的“数据”。 它可以被子类化以表示应用程序想要观察到的对象。
可观察对象可以有一个或多个观察者。 观察者可以是实现接口Observer的任何对象。 在可观察到的实例发生变化之后,调用Observable的notifyObservers方法的应用程序会使其所有观察者通过调用其update方法通知更改。

  通知的发送顺序是未指定的。 Observable类中提供的默认实现将以注册感兴趣的顺序通知Observers,但子类可能会更改此顺序,不使用保证的顺序,在单独的线程上发送通知,或者可以保证其子类遵循此顺序,因为它们选择。

  当新创建一个可观察对象时,其观察者集合为空。 当且仅当equals方法为它们返回true时,两个观察者被认为是相同的。

主要属性和方法
    //是否变化
    private boolean changed = false;
    //存放观察者容器
    private Vector<Observer> obs;

    /** Construct an Observable with zero Observers. */
    //构造函数
    public Observable() {
    //初始化观察者容器
        obs = new Vector<>();
    }
void addObserver(Observer o) 
将一个观察者添加到该对象的观察者组中,前提是它与集合中已有的一些观察者不一样。

int countObservers() 
返回此 Observable对象的观察者数。  

void deleteObserver(Observer o) 
从该对象的观察者组中删除观察者。  

void deleteObservers() 
清除观察者列表,使此对象不再有任何观察者。  

boolean hasChanged() 
测试此对象是否已更改。  

protected void setChanged() 
将此Observable对象标记为已更改; hasChanged方法现在将返回true 。

protected void clearChanged() 
表示此对象已不再更改,或已经通知其所有观察者其最近更改,以便 hasChanged方法现在将返回 false 。  

void notifyObservers() 
如果该对象发生了变化,由所示 hasChanged方法,则通知其所有观察者,并调用 clearChanged方法来指示该对象不再改变。  

void notifyObservers(Object arg) 
如果该对象发生了变化,由所示 hasChanged方法,则通知其所有观察者,并调用 clearChanged方法来指示该对象不再改变。  
 
属性

1)Observable含有一个boolean型的变量changed,代表是否发生改变,Observable类只提供这个boolean值来表明是否发生变化,而不定义什么叫变化,这是因为每个业务中对变化的具体定义不一样,因此需要子类来判断是否发生变化;该变量既提供了一种抽象(变与不变),同时提供了一种观察者更新状态的可延迟加载,通过后面的notifyObservers方法分析可知观察者是否会调用update方法,依赖于changed变量,因此即使被观察者在逻辑上发生改变了,只要不调用setChanged,update是不会被调用的。如果我们在某些业务场景不需要频繁触发update,则可以适时调用setChanged方法来延迟刷新。

2)Observable含有一个集合类Vector,该类泛型为Observer,主要用来存放所有观察自己的对象的引用,以便在更新时可以遍历集合中的观察者,逐个调用update方法。

方法

1)操作changed变量的方法为setChanged()设置变化状态,clearChanged()清除变化状态,这两个的访问权限都是protected,表明这两个方法由子类去调用,由子类来决定是否告诉观察者发生变化了,什么时候变化消失。都有同步关键字保证变量的读写操作线程安全。

2)操作Vector类型变量obs的方法为addObserver(Observer o), deleteObserver(Observer o), deleteObservers(),countObservers(),这四个方法分别实现了动态添加观察者,删除观察者,删除所有观察者,获取观察者数量。四个方法的访问权限都是公有的,这是提供给调用者的方法,让调用者来实时动态的控制哪些观察者来观察该被观察对象。

3)公开的方法notifyObservers(),notifyObservers(Object arg),该方法由调用者来操作,用来通知所有的观察者需要做更新操作了。

四、具体实例

  “在学校,上课铃声响了,学生进教师上课;下课铃声响了,学生下课休息;放学铃声响了,学生放学。”

实例分析

  涉及的对象包括:铃声和学生。学生根据铃声的变化进行相应的响应(上课、下课、放学)。不难发现,学生是观察者,铃声是学生观察的
对象。因此需要建立一个观察者类Listener实现Observer接口,并根据铃声的变化,进行上课、下课、放学。还需要创建一个观察目标,继承Observable。

代码
import java.util.Observable;
import java.util.Observer;

/**
 * 观察者
 * @author JavaProgress
 *         date 2020/1/7 19:26
 */
public class Listener implements Observer {
    /**
     * 学生姓名
     */
    private String name;

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

    @Override
    public void update(Observable o, Object arg) {
        switch (arg.toString()) {
            case "1":
                attendClass();
                break;
            case "-1":
                afterClass();
                break;
            case "0":
                afterSchool();
                break;
        }
    }

    /**
     * 上课
     */
    private void attendClass() {
        System.out.println(name + " 上课了");
    }

    /**
     * 下课
     */
    private void afterClass() {
        System.out.println(name + " 下课了");
    }

    /**
     * 放学
     */
    private void afterSchool() {
        System.out.println(name + " 下课了");
    }
}
import java.util.Observable;

/**
 * 观察目标
 *
 * @author JavaProgress
 *         date 2020/1/7 19:36
 */
public class RingSubject extends Observable {
    /**
     * 铃声
     *
     * @param num 1上课;-1下课;0放学
     */
    public void ring(String num) {
        switch (num) {
            case "1":
                System.out.println("上课铃响了");
                break;
            case "-1":
                System.out.println("下课铃响了");
                break;
            case "0":
                System.out.println("放学铃响了");
                break;
        }
        //改变
        setChanged();
        //通知观察者
        notifyObservers(num);
    }
}
/**
 * 观察者模式测试
 *
 * @author JavaProgress
 *         date 2020/1/7 19:43
 */
public class Test {
    public static void main(String[] args) {
        //创建观察目标
        RingSubject ringSubject = new RingSubject();
        for (int i = 0; i < 50; i++) {
            //创建观察者
            Listener listener = new Listener(String.valueOf(i + 1));
            //观察目标添加观察者
            ringSubject.addObserver(listener);
        }
        //调用,铃声响起
        ringSubject.ring("0");
    }
}

五、总结

5.1 观察者的优点

  5.1.1、观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。

  5.1.2、观察者模式在观察目标和观察者之间建立一个抽象的耦合。

 5.1.3、观察者模式支持广播通信。

 5.1.4、观察者模式符合“开闭原则”的要求。

5.2 观察者的缺点

  5.2.1、如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

  5.2.2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

  5.2.3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

5.3 观察者的使用场景

  5.3.1、一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。

  5.3.2、一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。

  5.3.3、一个对象必须通知其他对象,而并不知道这些对象是谁。

  5.3.4、需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

六维力传感器选型指南:电阻式vs电容式,哪个更适合你的工业场景? 本文深入解析六维力传感器在工业自动化中的选型要点,重点对比电阻式与电容式传感器的核心原理、环境适应性及成本结构。针对不同工业场景(如高精度装配、重载机器人等),提供专业选型建议,帮助工程师优化系统性能与经济效益。 阅读详情

相关推荐

5.1 滑模控制(SMC)及其改进

本文系统阐述了滑模控制(SMC)的基本原理及其在永磁同步电机(PMSM)控制系统中的应用。首先介绍了滑模控制的核心思想,包括滑模面设计和不连续控制律,其强鲁棒性使其在电机控制领域得到广泛应用。其次分析了SMC在PMSM速度控制器和无位置传感器观测器中的具体实现方案。重点探讨了SMC固有的抖振问题,详细比较了边界层法、高阶滑模和自适应方法等多种改进策略的优缺点。最后指出改进SMC的研究趋势是多种策略的融合应用,如自适应高阶滑模等,以在保持鲁棒性的同时有效抑制抖振。

技术工作者 1448

ssm毕设项目动态个人网站8j9pz(java+VUE+Mybatis+Maven+Mysql+sprnig)

Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。ssm毕设项目动态个人网站8j9pz(java+VUE+Mybatis+Maven+Mysql+sprnig)ssm + mybatis + Maven + Vue 等等组成,B/S模式 + Maven管理等等。2. 使用IDEA/Eclipse/MyEclipse导入项目,修改配置,运行项目;...

计算机程序设计 4274

关于海康网络摄像头使用VLC或者Opencv拉流有延迟的问题

先说结论,我用VLC或者Pyhton opencv直接拉取海康网络摄像头的rtsp流,会有1-2s延时,特别明显。环境:Windows + VLC / Openc-Python。如上面文章介绍,我使用的时候遇到一处错误,需要把代码中的。海康SDK:与网页视频相比,几乎是同步的。上面说的延时,也是与摄像头网页视频相比的。ffplay 去掉缓存:延时1s左右。这两处地方改成左斜杠,才能运行。opencv拉流使用的是。多线程:延时1s左右。

yljxh的博客 4498

大聪明教你学Java设计模式 | 第十三篇:观察者模式

大聪明在写代码的过程中发现设计模式的影子是无处不在,设计模式也是软件开发人员在软件开发过程中面临的一般问题的解决方案。大聪明本着“独乐乐不如众乐乐”的宗旨与大家分享一下设计模式的学习心得。

不肯过江东丶 656

Acute逻辑分析仪TL4134E实战:从触发电平到协议解析的完整避坑指南

本文是一份针对Acute逻辑分析仪TL4134E的实战避坑指南。文章深入解析了触发电平分组、采样率与存储深度权衡、高级触发等核心概念,并提供了混合电压系统测量、eMMC调试内存优化、SPI/I2C/UART协议解析排错等具体配置技巧,帮助硬件工程师和嵌入式开发者高效捕获与分析数字信号,快速定位通信问题。

weixin_29207149的博客 404

易康eCognition9.0分类|规则集和机器学习的方法的面向对象的多尺度分割分类

基于易康eCognition9.0软件的规则集和机器学习的方法的面向对象的多尺度分割分类

weixin_46493028的博客 1万+

观察者模式JAVA版---上课铃代码

ConcreteObserver1和ConcreteObserver2,两个具体观察者也就是老师和学生。共用一个Observer抽象观察者接口,只有一个response()方法。 ConcreteSubject具体目标类继承了Subject抽象目标类有抽象notifyObserve();//通知观察者方法。 重点是抽象目标Subject的代码:import java.util.Arr...

weixin_30363509的博客 176

TortoiseSVN的安装与使用

TortoiseSVN的安装与应用1、安装1.1、下载TortoiseSVN    点击下载TortoiseSvn1.2、下载汉化包。上面的页面中,找到Chinese, simplified汉化包,点击32位或者64位的Setup,下载汉化包。1.3、安装TortoiseSVN。在选择安装路径页面时要记得勾选“command line client tools”,默认不是勾选的。这里不勾选的话在I...

qq_28566071的博客 4万+

Java设计模式 -19- 观察者模式(Observer模式)

Java设计模式 -19- 观察者模式(Observer模式)前言模式的定义与特点优点:缺点:模式的结构与实现1. 模式的结构2. 模式的实现模式的应用实例模式的应用场景模式的扩展1. Observable类2. Observer 接口 前言 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组

Android系统工程师--小馬佩德罗 841

如何通过conda安装HyPhy教程

本文介绍了在Ubuntu系统上通过conda安装分子进化分析工具HyPhy的详细步骤。首先创建conda环境并指定Python 3.8版本,然后通过bioconda通道安装HyPhy软件包。安装完成后可通过conda list命令验证安装。文中还特别指出可能遇到的libcrypto.so.1.1共享库缺失错误,并提供了解决方案的参考链接。该教程配有安装过程截图,帮助用户直观了解操作流程和验证安装结果。

猿小白的博客 8260

RT-DETR训练前的准备,将数据集划分成训练集、测试集验证集(附完整脚本及使用说明)

在计算机视觉领域,当我们着手训练一个模型时,。其中,将数据集划分为和更是一项基础性且关键的操作。这篇博客分析了这一划分背后的原因、其重要意义以及如何通过代码实现,帮助大家更好地理解和运用这一技巧,。

Limiiiing的博客 906

java 观察者模式的实现及应用场景

最近项目中有个合同拆分功能,涉及到多个参数的联动,为了能更高效的实现该功能,我决定用观察者设计模式来完成这个功能。之前只是在网上了解过,具体实现细节已经忘光了,在这里写个小demo简单回忆一下 1.首先创建被观察者: import java.util.ArrayList; import java.util.Observable; /** * @Des: 被观察者 * @Author: liut * @Date: 2021/3/22 17:12 */ public class ContractDa

三3三的博客 985

YOLOv8 改进涨点 | 模块即插即用 直接可用

在目标检测任务中,注意力机制能够帮助模型聚焦于图像中的关键区域,显著提升检测精度。。创建模块代码注册模块修改任务解析tasks.py创建YAML配置文件模块核心优势适用场景计算开销SOCA捕获二阶统计信息,增强通道间相关性需要精细特征区分的场景中等SK自适应多尺度核选择多尺度目标检测中等偏高显式特征聚集-分配机制全局上下文建模中等A2-Net双线性注意力,高效全局交互复杂场景理解中等偏高CrissCross线性复杂度全局上下文高分辨率输入,长距离依赖较低。

u012133341的博客 2257

Java - 【设计模式】观察者模式(Observer Pattern)

设计模式 - 观察者模式(Observer Pattern) -> 解决问题:一个对象的状态发生改变,如何通知其他对象? 被观察对象(Subject) 观察对象(Observer) -> 注意: 互相指定,互相包含! 一:被观察对象(Subject) 1> 维护一个可变对象,该对象变化对应一个方法,该方法内部需要通知所有观察者(notifyAllObservers) private int state; public void setState(int state) {

⚡ 578

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java 设计模式——观察者模式(Observer Pattern)

    前言 一、简介 二、实现步骤 (1)实现方式: (2)举例: (3)步骤简化版: 三、代码实现 四、总结 五、Demo地址 六、参考文档 七、内容推荐 前言 本来没想写前言的,感觉就是一堆废话。那就当废话浏览一下吧,只是提醒一下自己一些注意的东西。 在许多博客当中看到把观察者模式又称呼为发布-订阅模式。其实我感觉两者确实很相似,但还是有一丢丢的区别: 在...

斌林诚上的博客 726

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Java设计模式之观察者模式

一、引子:观察者模式解决怎么样的问题、怎么解决 二、一张图说明观察者模式的结构 三、Java观察者模式代码示例 四、Java源码中的观察者模式

2164

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java设计模式-观察者模式(Observer Pattern)

观察者模式是软件设计模式中常见的一种,是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

IT熊的专栏 495

详解Java设计模式之观察者模式(Observer Pattern)

观察者模式又叫做发布-订阅(Publish/Subscribe)模式,模型-视图( Model/View)模式、源-监听器( Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。

Elegance never goes out of fashion 3627

JAVA设计模式之 观察者模式【Observer Pattern】

一、概念:   简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象。这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者对象能够自动更新。

小吕丶Code阶区 2088

Java常用设计模式--观察者模式(Observer Pattern)

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。 四个角色 Subject:抽象被观察者,把所有观察者对象的引用保存到集合中,然后 提供添加,移除,和通知观察者对象更新的方法。 ConcreteSubject:被观察者,集合存放观察者,重写增删和通知观察者 的方法,当发生变化时通知观...

gang_luo的博客 398

Java设计模式之观察者模式(Observer Pattern)

介绍 观察者模式是一种行为型设计模式,也叫做发布订阅模式(Publish/subcribe)。当一个对象发生改变时,多个对象需要得到通知,这个时候就需要利用观察者模式来实现。先看一下它的定义: Define a one-to-many dependency between objects so that when one object changes state, all its d...

落队的飞行兵 419

Java设计模式之观察者模式详解

在软件开发中,我们常常会遇到这样的场景:当一个对象的状态发生变化时,需要自动通知其他相关对象。这种场景下,观察者模式就派上了用场。观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系,当一个对象状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。接下来,我们将深入探讨Java中的观察者模式,并结合图文和代码示例进行详细讲解。

季鸢的博客 1298

Java设计模式-行为型设计模式-观察者模式

Java设计模式-行为型设计模式-观察者模式

Fatter$hday的博客 1715

Java设计模式--观察者模式【Observer Pattern】

自二胎政策放开后,越来越多的家庭将拥有两个宝宝。而大部分家庭都希望有儿有女,儿女齐全,这样的家庭无疑是幸福美满的。可是,许多家庭也由于无人照看孩子,而选择放弃生二胎。家庭条件的限制,给爸爸妈妈们留下了终生的遗憾。今天,我们就拿“照看”宝宝的例子,来切入到观察者模式的主题。   宝宝出生后,身边需要大人照顾。有些家庭只有宝宝的妈妈照顾,而有的家庭爷爷奶奶,外公外婆,七大姑八大姨都加入了照顾宝宝的行

CoderLover 463

Java设计模式之一:观察者模式

Java设计模式之一:观察者模式

杨荧的优快云博客 1万+

Java设计模式之观察者模式(Observer Pattern)

Observer Pattern 是一种常用的设计模式,它是一种事件监听模型,

停止更新 4481
上一篇: 使用Bintray发布library到JCenter中心
下一篇: 第一章 Thinking Reactively(响应式的思考)
Litepal
博客等级 码龄12年 17粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值