java设计模式之观察者模式

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

1、前言

        观察者模式:当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)又叫发布-订阅模式(Publish/Subscribe)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

2、应用场景及说明

       主要用来解决一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

从游戏角度出发,就是从被动定时拉取,变成主动推送的方式。比如红色警戒中【尤里】控制对方工具,只有【尤里】时候对方工具才能解除控制。这里解除控制的时候,就只直接通知对方工具解除控制。否则就可能出现对方工具定时检测【尤里】的是否存活来判断是否解除控制。

       从业务来讲,更多的应用在消息的推动上,比如委托方下单后,需要通知物流公司和库存的库管有一辆车即将进入你们系统。只需要物流系统和库存系统订阅委托方下单的功能,委托方下单后就会直接通知物流和库存,又比如车辆信息修改,也可以直接通知物流库存。

3、角色说明

从上面我们可以看到,这里面包含了两大类(主题和观察者)一共四个角色:

(1)Subject:抽象主题,他把所有观察者对象保存在一个集合里,可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。

(2)ConcreteSubject:具体主题,该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

(3)Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。

(4)ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

其中我们主题(Subject)就是车辆信息变化,具体的主题(ConcreteSubject)就是委托方下单业务,具体的观察者(ConcrereObserver)就是物流业务和库存业务

4、代码案例

UML类图:

抽象的主题:

/**
 * 主题
 *
 * @author: ws
 * @date: 2020/9/21 13:32
 */
public interface Subject {

    /**
     * 添加观察者
     * @param observer
     */
    void addObserver(Observer observer);

    /**
     * 删除观察者
     * @param observer
     */
    void removeObserver(Observer observer);

    /**
     * 通知观察者
     */
    void notifyObservers();
}

抽象的观察者:

/**
 * 观察者
 *
 * @author: ws
 * @date: 2020/9/21 13:40
 */
public interface Observer {
    void update();
}

具体的主题-车辆信息变更:

/**
 * 车辆更新/变化主题
 *
 * @author: ws
 * @date: 2020/9/21 13:34
 */
public class VehicleUpdateSubject implements Subject{

    // 线程安全的集合
    private Vector<Observer> vectors = new Vector<>();

    @Override
    public void addObserver(Observer observer) {
        vectors.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        vectors.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : vectors) {
            observer.update();
        }
    }

    public void vehicleUpdate(String msg){
        System.out.println("*******"+ msg +"********");
        this.notifyObservers();
    }
}

观察者-物流系统:

/**
 * 观察者-物流
 *
 * @author: ws
 * @date: 2020/9/21 13:45
 */
public class WlObservable implements Observer{

    private Subject subject;
    private String name;

    public WlObservable(Subject subject, String name) {
        this.subject = subject;
        this.name = name;

        subject.addObserver(this);
    }

    @Override
    public void update() {
        System.out.println("观察者:【"+name+"】接受到了通知!");
    }
}

观察者-库存系统:

/**
 * 观察者-仓库
 *
 * @author: ws
 * @date: 2020/9/21 13:49
 */
public class StoreObservable implements Observer{

    private Subject subject;
    private String name;

    public StoreObservable(Subject subject, String name) {
        this.subject = subject;
        this.name = name;

        subject.addObserver(this);
    }

    @Override
    public void update() {
        System.out.println("观察者:"+name+"接受到了通知!");
    }
}

客户端测试:

/**
 * 客户端测试
 *
 * @author: ws
 * @date: 2020/9/21 13:51
 */
public class PatternClient {

    public static void main(String[] args) {
        // 设置具体的主题
        VehicleUpdateSubject subject = new VehicleUpdateSubject();

        // 添加观察者(订阅主题)
        Observer wlObserver = new WlObservable(subject, "物流系统");
        Observer storeObserver = new WlObservable(subject, "库存系统");

        // 车辆发生改变
        subject.vehicleUpdate("委托方下单-新增车辆");
    }
}

执行结果:

5、分析观察者模式

不管是公司业务还是游戏中的尤里,使用观察者模式除了通知类的模式之外,这其实也是一种推拉模型。

  1. 推模型就是主动推送主题消息,不管观察者是否真的需要,只要订阅就会直接推送;
  2. 拉模型就是观察者根据自己需要被动拉取主题中的信息,但是并不知道主题中的信息什么时候更新。

6、观察者模式 VS 发布订阅模式(Pub-Sub Pattern)

观察者模式也叫发布-订阅模式,但是又区别我们常说的发布订阅。现在所说的发布订阅已经独立于观察者模式,成为另外一种不同的设计模式,以消息中间件最为常见。

观察者模式里面,update方法所在的实例对象,就是被观察者(Subject,或者叫Observable),它只需维护一套观察者(Observer)的集合,这些Observer实现相同的接口,Subject有改变时,直接通知所有观察者,至于观察者是否需要,主题并不关心,只要注册了,就会收到改变的信息。

发布订阅模式中发布者的消息发送者不会将消息直接发送给订阅者,而是通过第三个组件,该组件称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应地分发它们给订阅者。

7、观察者模式的延伸

  •     发布订阅:常用的消息中间件(消息队列),redis中的发布订阅等。其中以消息中间件最为常用,用来异步处理分布式系统中的消息通知问题,以此来解耦。
  •     Spring的事件机制(监听器)【ApplicationEvent , ApplicationListener】:Spring框架中事件机制(模型)非常多,比如各种监听器,第三方框架整合Spring时的事件触发(阿波罗)等

8、事件驱动模型案例

改造观察者模式,使用Spring事件机制模型。Spring事件机制中主要包含三要素:

  • 事件源(ApplicationEvent)
  • 监听器(ApplicationListener)
  • 发布事件者(ApplicationEventPublisher以及ApplicationEventMulticaster)

简要说明:

ApplicationEvent事件源是我们自定义的,ApplicationListener监听器是注册在Spring容器中的。ApplicationEventPublisher中ApplicationEventMulticaster类具备发布功能,当事件发布者发布事件之后,监听器监听到事件源就会执行相应的逻辑。

其中ApplicationListener相当于观察者模式中的观察者(Observe)。事件源相当于主题(Subject)。区别在于事件不会主动通知观察者,而是通过监听器这个中间介质来将两者关联起来的。

事件发布者我们可以自定义,也可以不定义。直接使用spring中的ApplicationContext来发布事件,该类继承了ApplicationEventPublisher类,具备发布事件的功能。

定义事件:

/**
 * 委托方下单事件
 *
 * @author: ws
 * @date: 2020/9/21 15:12
 */
public class BosOrderEvent extends ApplicationContextEvent {

    private String eventName;

    private String msg;

    public BosOrderEvent(ApplicationContext source, String eventName, String msg) {
        super(source);
        this.eventName = eventName;
        this.msg = msg;
    }

    public String getEventName() {
        return eventName;
    }

    public void setEventName(String eventName) {
        this.eventName = eventName;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

定义物流系统监听器:

/**
 * 物流监听
 *
 * @author: ws
 * @date: 2020/9/21 15:20
 */
public class WlListener implements ApplicationListener<BosOrderEvent>{

    @Override
    public void onApplicationEvent(BosOrderEvent event) {
        System.out.println("物流系统监控到:【"+event.getEventName()+"】事件被触发,通知消息为:"+event.getMsg());
    }
}

定义库存系统监听器:

/**
 * 库存监听器
 *
 * @author: ws
 * @date: 2020/9/21 15:20
 */
public class StockListener implements ApplicationListener<BosOrderEvent>{

    @Override
    public void onApplicationEvent(BosOrderEvent event) {
        System.out.println("库存系统监控到:【"+event.getEventName()+"】事件被触发,通知消息为:"+event.getMsg());
    }
}

事件发布类:

/**
 * 事件发布类
 *
 * @author: ws
 * @date: 2020/9/21 15:26
 */
public class BosOrderPublish implements ApplicationEventPublisherAware {

    // 获取Spring中的发布事件对象
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void publishEvent(ApplicationEvent event){
        System.out.println("发布事件被调用。。。。。");
        applicationEventPublisher.publishEvent(event);
    }
}

配置类:

/**
 * 委托方下单配置类
 *
 * @author: ws
 * @date: 2020/9/21 15:35
 */
@Configuration
public class BosOrderConfig {

    @Bean
    public WlListener wlListener(){
        return new WlListener();
    }

    @Bean
    public StockListener stockListener(){
        return new StockListener();
    }

    @Bean
    public BosOrderPublish bosOrderPublish(){
        return new BosOrderPublish();
    }

}

测试类:

public class BosOrderTest {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(BosOrderConfig.class);
        BosOrderEvent bosOrderEvent = new BosOrderEvent(context, "bos下单", "车辆更新");
        // context.publishEvent(bosOrderEvent);
        BosOrderPublish bosOrderPublish = (BosOrderPublish)context.getBean("bosOrderPublish");
        bosOrderPublish.publishEvent(bosOrderEvent);
    }
}

运行结果:

UML类图:

软件工程实验报告--用Visio绘制数据流图、ER图、状态图、软件结构图、程序流程图、系统流程图 用Visio绘制数据流图、ER图、状态图、软件结构图、程序流程图、系统流程图 阅读详情

相关推荐

Cadence导入tsmcN65GP PDK的完整流程与常见问题解析

本文详细介绍了Cadence导入tsmcN65GP PDK的完整流程,包括文件解压、目录结构解析、安装脚本运行及Cadence集成配置。重点解析了常见问题如文件路径错误、权限问题和工艺库显示不全的解决方案,并提供了实战技巧与优化建议,帮助用户高效完成PDK安装与配置。

weixin_29215391的博客 547

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

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

杨荧的优快云博客 1万+

BUCK电路三种工作模式全解析:CCM、BCM、DCM到底怎么选?

本文深入解析BUCK电路的CCM、DCM和BCM三种工作模式,通过对比其电流波形、效率、纹波及环路特性,提供基于计算公式的量化判断方法。文章结合电池供电、高精度模拟等具体应用场景,给出明确的模式选型策略与实战设计指南,帮助工程师根据核心需求做出最优决策。

ee345的博客 490

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

本文介绍了观察者模式的相关知识。

代码星辰的博客 6038

可信数据空间关键技术和功能架构研究

可信数据空间(TDS)是实现数据安全共享的基础设施,通过数字合约和使用控制技术确保数据跨域流通的可信与安全。其架构包括服务平台和接入连接器,关键技术涵盖访问控制、隐私计算、区块链等。评估重点在于合规性、连接器能力、互联互通及安全体系。核心在于构建规则引擎而非简单数据汇聚,连接器开发比平台建设更重要。当前面临技术成本博弈、跨域身份互认等挑战,需平衡安全、性能与成本,推动数据要素市场发展。

逸尘的专栏 2225

半导体AMHS系统振动控制技术演进:从0.5G到超低振动的工艺革命

在半导体制造进入埃米级时代后,AMHS的振动控制能力将成为区分厂商技术等级的标尺。国内企业通过“弹性机械设计-混合主动控制-智能调度”的三重创新,正逐步突破0.2G阈值,支撑12英寸晶圆厂向3nm/2nm制程升级。未来,振动抑制不再仅是物流系统的性能参数,而是与光刻、刻蚀等核心工艺深度耦合的基础能力,这将重塑半导体设备产业的竞争格局。

m0_60674045的博客 1585

Java设计模式之观察者模式

观察者模式(Observer),又叫发布-订阅模式(Publish/Subscribe),是一种行为型模式,定义对象间一对多的依赖关系(注册),使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新(通知)。Observer 接口是抽象观察者,它监视目标对象的变化,当目标对象发生变化时,观察者得到通知,并调用 void update(Observable o,Object arg) 方法,进行相应的工作。2.当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

cxbtdd的博客 2495

Windows报无法成功完成操作,因为文件包含病毒或潜在的垃圾软件的解决方法

Windows报无法成功完成操作,因为文件包含病毒或潜在的垃圾软件的解决方法 在Windows的搜索框中输入Windows安全中心,搜索到后将其打开 点击病毒和威胁防护将鼠标移动到Microsoft Defender防病毒选项处,将定期扫描打开 下滑找到管理设置 先关闭篡改防护,再点击添加或删除排除项 先点击添加排除项,再点击文件,选择报出异常的文件,将其添加到排除项中,过程中会存在跳框确认,皆点击确定,完成后就可以运行报无法成功完成操作,因为文件包含病毒或潜在的垃圾软件异常的文件

123 2万+

Java实现常用设计模式之观察者模式

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。如何解决:使用面向对象技术,可以将这种依赖关系弱化。关键代码:在抽象类里有一个 ArrayList 存放观察者们。应用实例: 1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。

xtho62的博客 7177

Universal Robot——在Gazebo中模拟UR5机器人

今天的目标是在Gazebo安装我们的ur5机器人。Gazebo是一个流行的模拟工具,它不仅可以让你像在Rviz中一样可视化你的机器人,而且还内置了一个物理引擎。这样你就可以在更真实的环境中测试你的机器人应用程序。我们将查看我们需要的属性 添加对我们的机器人——我们的order的描述,以模拟它以及如何在Gazebo中生成我们的机器人。

如果想成为中心,那么就到中心去吧。 1970

腾讯音乐 QQ音乐商业化客户端开发工程师:岗位深度解析与面试攻略

腾讯音乐QQ音乐商业化客户端开发工程师岗位要求3年以上Android开发经验,熟练掌握Kotlin/Java及跨端开发技术。核心职责包括QQ音乐客户端功能开发、架构优化、性能提升及技术攻关。岗位要求计算机相关本科以上学历,具备完整项目开发经验,熟悉TCP/IP等网络协议,能独立解决复杂技术问题。面试重点考察项目经验、架构设计、性能优化及新技术研究能力,建议候选人准备具体案例,量化成果,并熟悉Flutter等跨端技术。该职位强调技术深度与产品思维的结合,需展现扎实的编程基础、问题解决能力和团队协作精神。

郑伟强dev的专栏 367

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

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

⚡ 579

fastlio2原理详解

其核心是利用IMU的高频数据(通常100-500Hz)进行状态预测(前向传播),同时利用激光雷达扫描(通常10-100Hz)作为观测来校正状态。转换了卡尔曼增益的计算公式,将对大维度观测矩阵的求逆(点云数量级)转换为对小维度状态矩阵的求逆,从而极大提升了计算效率。:利用预测出的连续IMU状态,将一帧内每个激光点根据其时间戳反向插值,统一校正到扫描结束时刻,输出无畸变的点云。收敛后,用最终的状态将本帧点云。,根据其精确的时间戳,利用前后两个IMU位姿进行插值,计算出该点采集时刻的精确位姿,再将其全部。

Studying…… 103

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

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

斌林诚上的博客 727

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

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

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

IT熊的专栏 495

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

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

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

Elegance never goes out of fashion 3629

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

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

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

小吕丶Code阶区 2088

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

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

gang_luo的博客 399

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设计模式--观察者模式【Observer Pattern】

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

CoderLover 463

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

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

Fatter$hday的博客 1715

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

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

停止更新 4481

java设计模式(十八)观察者模式(Observer Pattern)

观察者模式(Observer Pattern)的模式介绍、应用场景、优缺点以及代码示例讲解

weixin_70044963的博客 425
上一篇: springboot集成webSocket实现网络实时通讯
下一篇: 重试框架spring-retry的探索与揭秘
智_永无止境
博客等级 码龄10年 803粉丝 406原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智_永无止境

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值