观察者模式及应用场景

嵌入式Linux Qt应用程序卡死问题分析记录 根据应用和系统层面的分析,软件功能异常和卡死现象的原因是系统控制台/dev/console阻塞导致依赖其的相关应用和命令异常。系统控制台/dev/console阻塞的原因还未确定,最近的软件版本和其他测试同事未出现该问题,所以很大可能是串口线的问题,待后续有进展了继续更新。 阅读详情

观察者模式(Observer Design Pattern),也叫做发布订阅模式(Publish-Subscribe Design Pattern)、模型-视图(Model-View)模式、源-监听器(Source-Listener)模式、从属者(Dependents)模式。指在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

比如说Redis 中的基于频道的发布订阅就是观察者模式的应用:

一、观察者模式的介绍

观察者模式是一种对象行为型模式,下面就来看看观察者模式的结构及其实现:

1.1 观察者模式的结构

观察者模式结构中主要包括观察目标(Object)和观察者(Observer)主要结构:

SubjectConcreteSubjectObserverConcreteObserver1、ConcreteObserver2Client

1.2 观察者模式的实现

根据上面的类图,我们可以实现对应的代码。

首先定义一个抽象目标类 Subject ,其中包括增加、注销和通知观察者方法

public abstract class Subject {    protected List<Observer> observerList = new ArrayList<Observer>();    /**     * 增加观察者     * @param observer 观察者     */    public void add(Observer observer) {        observerList.add(observer);    }    /**     * 注销观察者,从观察者集合中删除一个观察者     * @param observer 观察者     */    public void remove(Observer observer) {        observerList.remove(observer);    }    /**通知观察者*/    public abstract void notifyObserver();}

对应具体的目标类 ConcreteSubject

public class ConcreteSubject extends Subject{    @Override    public void notifyObserver() {        System.out.println("遍历观察者:");        for (Observer observer : observerList) {            observer.response();        }    }}

此外需要定义抽象观察者 Observer ,它一般定义为一个接口,声明一个 response() 方法,为不同观察者的相应行为定义相同的接口:

public interface Observer {    /**声明响应方法*/    void response();}

具体的观察者实现:

public class ConcreteObserver1 implements Observer{    @Override    public void response() {        System.out.println("我是具体观察者ConcreteObserver1");    }}public class ConcreteObserver2 implements Observer{    @Override    public void response() {        System.out.println("我是具体观察者ConcreteObserver2");    }}

最后是客户端测试:

public class Client {    public static void main(String[] args) {        Subject concreteSubject = new ConcreteSubject();        //具体观察者        Observer concreteObserver1 = new ConcreteObserver1();        Observer concreteObserver2 = new ConcreteObserver2();        concreteSubject.add(concreteObserver1);        concreteSubject.add(concreteObserver2);                concreteSubject.notifyObserver();    }}

测试结果:

遍历观察者:我是具体观察者ConcreteObserver1我是具体观察者ConcreteObserver2

二、观察者模式的应用场景

在以下情况就可以考虑使用观察者模式:

  1. 一个对象的改变会导致一个或多个对象发生改变,而并不知道具体有多少对象将会发生改变,也不知道这些对象是谁
  2. 当一个抽象模型有两个方面,其中的一个方面依赖于另一个方面时,可将这两者封装在独立的对象中以使他们可以各自独立地改变和复用
  3. 需要在系统中创建一个触发链,使得事件拥有跨域通知(跨越两种观察者的类型)

2.1 观察者模式在java.util包中的应用

观察者模式在JDK中就有典型应用,比如 java.util.Observable 和 java.util.Observer 类。结构如下图所示:

我们可以通过实现具体的 ConcreteObserver 和具体的 ConcreteObservable 完成观察者模式流程

2.2 观察者模式在MVC中的应用

MVC(Modew-View-Controller)架构中也应用了观察者模式,其中模型(Model)可以对应观察者模式中的观察目标,而视图(View)对应于观察者,控制器(Controller)就是中介者模式的应用:

三、观察者模式实战

在本案例中模拟北京小客车指标摇号事件的通知场景(来源于《重学Java设计模式》)

对于通知事件,可以将其分成三个部分: 事件监听 、 事件处理 和 具体的业务流程 ,如下图所示:

对于和核心流程和非核心流程的结构,非核心流程可以是异步的,在MQ以及定时任务的处理下,能够最终保证一致性。

具体代码实现

  1. 事件监听接口及具体实现

这个部分就相当于观察者(Observer)的角色

在接口中定义基本事件类方法 doEvent()

public interface EventListener {    void doEvent(LotteryResult result);}

监听事件的具体实现 MessageEventListener (短消息事件)和 MQEventListener (MQ发送事件)

public class MessageEventListener implements EventListener{    private Logger logger = LoggerFactory.getLogger(MessageEventListener.class);    @Override    public void doEvent(LotteryResult result) {        logger.info("给用户 {} 发送短信通知(短信):{}", result.getuId(), result.getMsg());    }}public class MQEventListener implements EventListener{    private Logger logger = LoggerFactory.getLogger(MQEventListener.class);    @Override    public void doEvent(LotteryResult result) {        logger.info("记录用户 {} 摇号结果(MQ):{}", result.getuId(), result.getMsg());    }}
  1. 事件处理类

该部分就相当于主题(Object)部分

对于不同的事件类型(MQ和Message)进行枚举处理,并提供三个方法: subscribe() 、 unsubscribe() 和 notify() 用于对监听事件的注册和使用:

public class EventManager {    Map<Enum<EventType>, List<EventListener>> listeners = new HashMap<>();    public EventManager(Enum<EventType>... operations) {        for (Enum<EventType> operation : operations) {            listeners.put(operation, new ArrayList<>());        }    }    public enum EventType {        MQ,        Message    }    /**     * 订阅     * @param eventType 事件类型     * @param listener  监听     */    public void subscribe(Enum<EventType> eventType, EventListener listener) {        List<EventListener> eventListeners = listeners.get(eventType);        eventListeners.add(listener);    }    /**     * 取消订阅     * @param eventType 事件类型     * @param listener 监听     */    public void unsubscribe(Enum<EventType> eventType, EventListener listener) {        List<EventListener> eventListeners = listeners.get(eventType);        eventListeners.remove(listener);    }    /**     * 通知     * @param eventType 事件类型     * @param result    结果     */    public void notify(Enum<EventType> eventType, LotteryResult result) {        List<EventListener> eventListeners = listeners.get(eventType);        for (EventListener eventListener : eventListeners) {            eventListener.doEvent(result);        }    }}
  1. 业务抽象类接口及其实现

使用抽象类的方式实现方法,好处是可以在方法中扩展额外的调用,并提供抽象方法 doDraw ,让继承者去实现具体的逻辑

public abstract class LotteryService {    private EventManager eventManager;    public LotteryService() {        eventManager = new EventManager(EventManager.EventType.MQ, EventManager.EventType.Message);        eventManager.subscribe(EventManager.EventType.MQ, new MQEventListener());        eventManager.subscribe(EventManager.EventType.Message, new MessageEventListener());    }    public LotteryResult draw(String uId) {        LotteryResult lotteryResult = doDraw(uId);        eventManager.notify(EventManager.EventType.MQ, lotteryResult);        eventManager.notify(EventManager.EventType.Message, lotteryResult);        return lotteryResult;    }    protected abstract LotteryResult doDraw(String uId);}public class LotteryServiceImpl extends LotteryService{    private MinibusTargetService minibusTargetService = new MinibusTargetService();    @Override    protected LotteryResult doDraw(String uId) {        //摇号测试        String lottery = minibusTargetService.lottery(uId);        return new LotteryResult(uId, lottery, new Date());    }}
  1. 其他的类

摇号服务接口:

/** * 小客车指标调控服务 */public class MinibusTargetService {    /**     * 模拟摇号,但不是摇号算法     *     * @param uId 用户编号     * @return 结果     */    public String lottery(String uId) {        return Math.abs(uId.hashCode()) % 2 == 0 ? "恭喜你,编码".concat(uId).concat("在本次摇号中签") : "很遗憾,编码".concat(uId).concat("在本次摇号未中签或摇号资格已过期");    }}

事件信息返回类:

public class LotteryResult {    private String uId;    private String msg;    private Date dateTime;    //get set constructor... }
  1. 测试类
public class ApiTest {    private Logger logger = LoggerFactory.getLogger(ApiTest.class);    @Test    public void test() {        LotteryServiceImpl lotteryService = new LotteryServiceImpl();        LotteryResult result = lotteryService.draw("1234567");        logger.info("摇号结果:{}", JSON.toJSONString(result));    }}

测试结果:

11:43:09.284 [main] INFO  c.e.d.event.listener.MQEventListener - 记录用户 1234567 摇号结果(MQ):恭喜你,编码1234567在本次摇号中签11:43:09.288 [main] INFO  c.e.d.e.l.MessageEventListener - 给用户 1234567 发送短信通知(短信):恭喜你,编码1234567在本次摇号中签11:43:09.431 [main] INFO  ApiTest - 摇号结果:{"dateTime":1649475789279,"msg":"恭喜你,编码123
华为云Stack扩容实战:从CMDB配置到计算节点增减容,一份避坑指南 本文详细解析华为云Stack扩容实战,从CMDB配置到计算节点增减容的全流程操作指南。通过典型场景案例和避坑建议,帮助企业高效管理计算资源扩容与减容,确保业务连续性。特别针对华为云Stack的弹性扩容能力提供专业指导,涵盖存储、网络及自动化工具链的配合使用。 阅读详情

相关推荐

程序员未来真的会被淘汰吗?

实际上的计算机:web,图形学Q,Linux系统开发,一系列嵌入式开发,数据库,高性能服务器,中间件开发,三维建模,网络安全,通信协议°,加密算法,服务器集群维护,文件存储引擎Q,编译器,工业软件,客户端,计算机视觉,自然语言处理,算法调优,游戏引擎Q。实际上的计算机:web,图形学Q,Linux系统开发,一系列嵌入式开发,数据库,高性能服务器,中间件开发,三维建模,网络安全,通信协议°,加密算法,服务器集群维护,文件存储引擎Q,编译器,工业软件,客户端,计算机视觉,自然语言处理,算法调优,游戏引擎Q。

——心比天高,仗剑走天涯,保持热爱,奔赴向梦想!低调,谦虚,自律,反思,成长,还算是比较正能量的博主,公益免费传播……内心特别想在AI界做出一些可以推进历史进程影响力的东西(兴趣使然,有点小情怀,也有点使命感呀)… 1263

观察者模式及其应用场景

观察者模式(Observer Design Pattern),也叫做发布订阅模式(Publish-Subscribe Design Pattern)、模型-视图(Model-View)模式、源-监听器(Source-Listener)模式、从属者(Dependents)模式。指在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。 比如说Redis 中的基于频道的发布订阅就是观察者模式的应用: 一、观察者模式的介绍 观察者模式是一种对象行为型模式,下面就来看看观察者模式

hello_1566的博客 6397

吐血总结《Mysql从入门到入魔》,图文并茂

文章目录1. 查询1.1 查询多列1.2 检索唯一值1.3 限制输出1.4 注释2. ORDER BY 排序2.1 单列排序3.2 多列排序3.3 指定排序方向4. WHERE 过滤数据4.1 WHERE 子句操作符4.2 范围值检查4.3 空值检查5. 高级数据过滤5.1 WHERE 组合过滤5.2 IN 操作符5.3 NOT 操作符6. 通配符过滤6.1 % 通配符6.2 _ 通配符7. 创建计算字段7.1 计算字段7.2 拼接字段7.3 执行算数计算8. 函数8.1 常用文本处理函数8.2 日期和时间

向日葵的专属太阳 3万+

设计模式:观察者模式,详解各种应用场景下观察者模式的不同实现方式

引入 设计模式可以分为三类:创建型、结构型、行为型 创建型设计模式主要解决“对象的创建”问题 结构型设计模式主要解决“类或对象的组合或组装”问题 行为型设计模式主要解决“类或对象之间的交互”问题 行为型设计模式比较多,有11个,几乎占了 23 种经典设计模式的一半。它们分别是:观察者模式、模板模式、策略模式、职责链模式、状态模式、迭代器模式、访问者模式、备忘录模式、命令模式、解释器模式、中介模式。 这里我们主要关注观察者模式,也是实际中用的比较多的一种模式。 原理 观察者模式(Observer Desi

OceanStar的博客 3007

从仿真到实物:Realsense D435+ROS2焊接机械臂的视觉标定与数据验证指南

本文详细介绍了如何将Realsense D435相机与ROS2焊接机械臂从仿真环境迁移到实物部署的全过程。通过视觉标定、数据验证和焊接场景优化,确保系统在真实环境中精准可靠。重点讲解了硬件配置、驱动优化、数据一致性验证及焊接应用的特殊处理,为工业自动化开发者提供实用指南。

weixin_28701593的博客 408

从原理到实战:ARS548 4D毫米波雷达数据处理与多模态融合全解析

本文深入解析了4D毫米波雷达ARS548的工作原理与数据处理全流程。从FMCW测距测速、MIMO虚拟天线阵列到点云生成的三步FFT处理,提供了详尽的Python代码实现。文章进一步探讨了与激光雷达、相机的多模态时空对齐与融合策略,并指导如何构建用于自动驾驶感知训练的多模态标注数据集,为相关算法工程师提供了从理论到实践的完整指南。

weixin_29161719的博客 369

Java中的观察者模式应用场景

观察者模式(Observer Pattern)在Java中是一种常用的设计模式,主要用于实现当一个对象的状态发生变化时,其相关联的一组对象都能够得到通知并自动更新。以上就是Java中观察者模式的一些应用场景。这种模式的核心思想是将对象之间的依赖关系从硬编码的方式变为更加灵活、松耦合的方式,从而提高系统的可维护性和可扩展性。

api77的博客 2601

基于Pixi.js的Live2D看板娘离线加载实战指南

本文详细介绍了基于Pixi.js实现Live2D看板娘离线加载的完整方案,涵盖环境搭建、模型加载、交互功能实现及常见问题解决。通过Pixi.js的硬件加速优势,开发者可在Web和Electron项目中无缝集成离线运行的Live2D模型,提升用户体验并避免网络依赖问题。

weixin_29001423的博客 344

【设计模式——学习笔记】23种设计模式——观察者模式Observer(原理讲解+应用场景介绍+案例介绍+Java代码实现)

讲解观察者模式的思想,介绍其常见的应用场景,举例说明其实现方式

我只管埋头前行,剩下的交给时间。 3560

【Ubuntu】RK3576 Linux 6.10 Ubuntu 22.04 系统中 HUSB311 Type-C 转 DP 显示输出与 Device/OTG 模式切换配置详解

本文详细介绍了在Rockchip RK3576开发板(Linux Kernel 6.10+Ubuntu 22.04)上配置HUSB311 Type-C控制器的设备树实现方案。主要内容包括:1)硬件连接与模块组成;2)设备树完整配置,涵盖Type-C供电、USB OTG/Host模式、DP显示输出等关键功能;3)软件配置步骤与常见问题排查方法。该方案实现了Type-C接口的DisplayPort AltMode显示输出、USB Device/Host模式自动切换等功能,为嵌入式系统Type-C接口开发提供参考

qq_34478161的博客 808

大数据分析案例-基于随机森林模型对北京房价进行预测

自1998年我国取消了福利分房的政策后,房地产市场迅速开展蓬勃起来。同时,随着社会经济的快速开展,居民的经济条件越来越好,住房条件也在不断地提升。而住房是人民根本生活的保障,也是-一个家庭最重要的资产,从一定的层面.上反映了一个家庭整体的生活水王,多方面的因素使得房地产行业在短时间开展成为我国的支柱产业之一;成为了切实关乎人民生活和利益的重要产业。然而,随着房地产行业的开展,问题也慢慢突显出来,房价一直居高不下成为了一个大问题。 作为国家的支柱产业,房地产的稳定发展关乎国计民生。近几年,房

m0_64336780的博客 8827

设计模式内容分享(二十一):观察者模式

实现观察者模式的时,发布者和观察者之间不能直接调用,否则会使发布者和观察者之间紧密的耦合,从根本上违反面向对象的设计的原则。

之乎者也·的博客 2612

MuJoCo XLA (MJX) 强化学习人形机器人四足机器人入门教程(三)

MJX 是用 JAX 编写的 MuJoCo 实现,可以在 GPU/TPU 上进行大批量训练。在本笔记本中,我们将演示如何使用 MJX 训练 RL 策略。在开始大量 RL 工作负载之前,我们先从一个简单的示例开始!xml = """"""接下来,我们使用 MJX 将 MuJoCo 模型和数据放到 GPU 设备上。下面,我们将打印来自 MuJoCo 和 MJX 的 qpos。

2506_90492529的博客 2473

观察者模式的应用场景

观察者模式(Observer Pattern)定义了对象之间的一对多依赖,让多个观察者对象同时监听一个主体对象,当主体对象发生变化时,它的所有依赖者(观察者)都会收到通知并更新,属于行为型模式。观察者模式有时也叫做发布订阅模式。观察者模式主要用于在关联行为之间建立一套触发机制的场景。观察者模式在现实生活应用也非常广泛,比如:微信朋友圈动态通知、消息通知、邮件通知、广播通知、桌面程序的事件响应等(如下图)。 现在大家都用过我们的生态圈了,当小伙伴们在生态圈中提问的时候,如果有设置指定老师回答,对应的老师

Leon_Jinhai_Sun的博客 4894

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

java 观察者模式 场景_Java设计模式之《观察者模式》及应用场景

一、观察者模式观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察者知道情况,其实是由目标将情况发送到观察者的。在现实生活中,警察抓小偷是一个典型的观察者模式「这以一个惯犯在街道逛街然后被抓为例子」,这里小偷就是被观察者,各个干警就是观察者,干警时时观察着小偷,当小偷正在偷东西「就...

weixin_42202595的博客 473

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

解释单例模式、工厂模式和观察者模式的原理和应用场景

这个模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。工厂模式是一种创建型设计模式,它提供了一种封装机制来将对象的创建与使用分离,使得代码更加灵活和可扩展。在工厂模式中,我们创建工厂对象,该对象包含用于实例化对象的必要逻辑,而不是在客户端代码中直接创建对象。观察者模式是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。例如,股票价格监控系统,当股票价格发生变动时,所有关注这个股票的用户都需要收到通知并更新他们的股票信息。

m0_46552684的博客 580

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

《设计模式之美》观察者模式(上):详解各种应用场景 下观察者模式的不同实现方式

王争《设计模式之美》学习笔记 行为型设计模式主要解决的就是“类或对象之间的交互”问题。 一个行为型设计模式,也是在实际的开发中用得比较多的一种模式:观察者模式。 观察者模式会对应不同的代码实现方式: 有同步阻塞的实现方式,也有异步非阻塞的实现方式; 有进程内的实现方式,也有跨进程的实现方式。 原理及应用场景剖析 观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Patter)。 在对象之间定义一个一对多的依赖,当一

玲珑巫女的学习笔记 282

观察者模式(上):详解各种应用场景下观察者模式的不同实现方式

观察者模式,根据应用场景的不同,观察者模式会对应不同的代码实现方式:有同步阻塞的实现方式,也有异步非阻塞的实现方式;有进程内的实现方式,也有跨进程的实现方式。今天我会重点讲解原理、实现、应用场景。下一节课,我会带你一块实现一个基于观察者模式的异步非阻塞的 EventBus,加深你对这个模式的理解。 原理及应用场景剖析 观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)。在 GoF 的《设计模式》一书中,它的定义

zhujiangtaotaise的专栏 1617

浅淡java观察者模式及应用场景

定义: 指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。 优点: 1、降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。 2、目标与观察者之间建立了一套触发机制。 缺点: 1、目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。 2、当观察者对象很多时...

qq1170993239的博客 611

观察者模式 - 观察者模式的应用场景

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象的状态发生变化时,所有依赖于它的观察者对象都会收到通知并自动更新。观察者模式是一种非常实用的设计模式,它通过定义对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。观察者模式广泛应用于事件处理系统、GUI框架、消息队列等场景中。希望本文能帮助你更好地理解观察者模式的概念、实现方式以及应用场景。如果你有任何问题或建议,欢迎在评论区留言讨论。

2301_81482480的博客 1890

Java面试必备:观察者模式详解概念、应用场景与实例解析

观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,它会自动通知所有观察者对象,使它们能够自动更新自己。

qq_58299462的博客 894

设计模式学习笔记:观察者模式及应用场景

观察者模式(Observer Design Pattern),也叫做发布订阅模式(Publish-Subscribe Design Pattern)、模型-视图(Model-View)模式、源-监听器(Source-Listener)模式、从属者(Dependents)模式。指在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。 比如说Redis 中的基于频道的发布订阅就是观察者模式的应用: 一、观察者模式的介绍 观察者模式是一种对象行为型模式,下面就来看

Trouvailless的博客 225

java观察者模式应用_Java设计模式之《观察者模式》及应用场景

观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察者知道情况,其实是由目标将情况发送到观察者的。观察者模式多用于实现订阅功能的场景,例如微博的订阅,当我们订阅了某个人的微博账号,当这个人发布了新的消息,就会通知我们。现在我们举一个类似的情况,并使用代码来实现,为大家提供一个比较明...

weixin_27872611的博客 221
上一篇: 排查Spring 无法启动的问题
下一篇: RabbitMQ 补偿机制的办法
Java_ttcd
博客等级 码龄4年 198粉丝 190原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值