事件驱动设计模式

news2024/11/24 12:33:23

是一种常见的设计模式,其核心思想是:系统中发生的事件会触发相应的事件处理器或监听器,从而实现特定的业务逻辑或功能
该设计模式通常由以下几个要素组成:

  • 事件源(Event Source):事件源是指发生事件的对象或组件,它负责产生事件并向事件处理器传递事件对象。
  • 事件对象(Event Object):事件对象是一种数据结构,用于封装事件源发生的事件信息,以便事件处理器进行处理。
    事件处理器(Event Handler):事件处理器是一段代码,用于处理特定类型的事件。当事件源产生事件时,它会将事件对象传递给相应的事件处理器进行处理。
  • 监听器(Listener):监听器是事件处理器的一种特殊形式,它通常用于处理 GUI 事件、网络事件、数据库事件等需要异步处理的事件类型。
    在事件驱动设计模式中,事件源和事件处理器之间通常采用观察者模式进行通信。事件源作为被观察者,事件处理器作为观察者,事件源会将事件对象通知给所有注册的事件处理器,事件处理器接收到事件后进行相应的处理。
    事件驱动设计模式的优点包括:降低系统的耦合度、提高系统的可扩展性、增强系统的灵活性和可重用性。

事件驱动架构是一种常见的软件设计架构,它包括多个组件之间的事件交互。在事件驱动的架构中,事件是所有通信的中心点,组件通过订阅和发布事件来进行通信。下面是几种常见的事件驱动设计模式:

  1. 观察者模式(Observer Pattern):观察者模式是一种经典的事件驱动设计模式。在这个模式中,一个被观察者对象(也称为主题)会维护一组观察者对象,当主题发生变化时,会通知所有观察者对象进行更新。

  2. 发布-订阅模式(Publish-Subscribe Pattern):发布-订阅模式是一种广泛应用的事件驱动设计模式。在这个模式中,发布者对象将事件发布到一个或多个主题,而订阅者对象可以选择订阅感兴趣的主题并接收事件通知。

  3. 命令模式(Command Pattern):命令模式是一种将请求封装成对象的设计模式。在事件驱动架构中,命令模式可以用于将事件请求封装成命令对象,使得请求发送者和请求接收者能够解耦。

  4. 代理模式(Proxy Pattern):代理模式是一种结构型设计模式,它可以为其他对象提供一种代理以控制对这个对象的访问。在事件驱动架构中,代理模式可以用于代理事件发布者,从而对事件进行过滤或转换。

  5. 责任链模式(Chain of Responsibility Pattern):责任链模式是一种行为型设计模式,它可以将请求从一个对象传递到另一个对象,直到请求被处理为止。在事件驱动架构中,责任链模式可以用于将事件请求传递给一系列处理对象,直到找到可以处理事件的对象为止。

  6. 状态模式(State Pattern):状态模式是一种行为型设计模式,它可以将对象的状态封装成不同的类,并将状态转换的逻辑委托给状态类。在事件驱动架构中,状态模式可以用于管理对象的状态,当事件发生时,对象可以根据其当前状态进行相应的处理。

  7. 访问者模式(Visitor Pattern):访问者模式是一种行为型设计模式,它可以在不修改被访问对象的前提下,对对象的结构进行操作。在事件驱动架构中,访问者模式可以用于处理事件时访问事件对象的各个属性和方法。

  8. 中介者模式(Mediator Pattern):中介者模式是一种行为型设计模式,它可以通过将对象之间的通信集中到一个中介者对象中,从而减少对象之间的耦合。在事件驱动架构中,中介者模式可以用于将事件发送给中介者对象,由中介者对象决定哪些对象需要接收事件。
    在这里插入图片描述

观察者设计模式示例

#include <iostream>
#include <vector>
using namespace std;

class Observer
{
public:
    virtual void update() = 0;
};

class Subject
{
public:
    virtual void attach(Observer* obs) = 0;
    virtual void detach(Observer* obs) = 0;
    virtual void notify() = 0;
};

class ConcreteObserver : public Observer
{
public:
    void update() override {
        cout << "Observer is notified of event." << endl;
    }
};

class ConcreteSubject : public Subject
{
public:
    void attach(Observer* obs) override {
        observers.push_back(obs);
    }
    void detach(Observer* obs) override {
        auto it = find(observers.begin(), observers.end(), obs);
        if (it != observers.end()) {
            observers.erase(it);
        }
    }
    void notify() override {
        for (auto obs : observers) {
            obs->update();
        }
    }
private:
    vector<Observer*> observers;
};

int main()
{
    ConcreteSubject subject;
    ConcreteObserver observer1, observer2;
    subject.attach(&observer1);
    subject.attach(&observer2);
    subject.notify();
    subject.detach(&observer1);
    subject.notify();
    return 0;
}

在 ConcreteObserver 类中,我们实现了 update 函数,用于在观察者收到事件通知时执行的操作。在 ConcreteSubject 类中,我们实现了 attach、detach 和 notify 函数,分别用于添加、移除和通知观察者。
在主函数中,我们创建了一个 ConcreteSubject 对象和两个 ConcreteObserver 对象,并将观察者对象添加到被观察者对象中。然后,我们调用 notify 函数,观察者对象将会接收到事件通知并执行相应的操作。接着,我们将一个观察者对象从被观察者对象中移除,并再次调用 notify 函数,只有一个观察者对象会收到事件通知。
需要注意的是,这只是观察者模式的一个简单示例,实际应用中可能需要更复杂的代码结构和设计。此外,其他事件驱动设计模式的实现方式和代码结构也各不相同,需要根据具体的情况进行设计和实现。

命令模式示例

#include <iostream>
#include <vector>
using namespace std;

class Command
{
public:
    virtual void execute() = 0;
};

class Receiver
{
public:
    void action() {
        cout << "Receiver is executing action." << endl;
    }
};

class ConcreteCommand : public Command
{
public:
    ConcreteCommand(Receiver* receiver) : receiver(receiver) {}
    void execute() override {
        receiver->action();
    }
private:
    Receiver* receiver;
};

class Invoker
{
public:
    void setCommand(Command* cmd) {
        command = cmd;
    }
    void executeCommand() {
        if (command != nullptr) {
            command->execute();
        }
    }
private:
    Command* command = nullptr;
};

int main()
{
    Receiver receiver;
    ConcreteCommand command(&receiver);
    Invoker invoker;
    invoker.setCommand(&command);
    invoker.executeCommand();
    return 0;
}

在这个示例中,我们定义了三个抽象基类 Command、Receiver 和 Invoker,以及两个具体类 ConcreteCommand 和 Receiver。其中,Command 类表示命令,Receiver 类表示命令的接收者,Invoker 类表示调用者。ConcreteCommand 类表示具体的命令实现。
在 Command 类中,我们定义了 execute 函数,用于执行命令。在 Receiver 类中,我们定义了 action 函数,表示接收者要执行的操作。在 ConcreteCommand 类中,我们实现了 execute 函数,并在构造函数中传递了一个 Receiver 对象指针,用于执行接收者的操作。在 Invoker 类中,我们定义了 setCommand 和 executeCommand 函数,分别用于设置和执行命令。

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

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

相关文章

C++数据结构 —— AVL树

目录 1.AVL树介绍 2.AVL树如何进行平衡调整 2.1平衡因子 2.2AVL树的插入 2.3左单旋 2.4右单旋 2.5左右双旋 2.6右左双旋 2.8完整代码 3.测试用例 4.验证是否为AVL树 1.AVL树介绍 AVL树是map/set/multimap/multi/set等容器的一种底层结构&#xff0c;其本质就是一颗…

推荐系统算法总览【持续学习ing】

推荐系统整体知识架构 推荐模型发展 工业 CTR模型的三个改进大点&#xff1a;显性特征交叉&#xff0c; 特征重要度&#xff0c; user历史信息的挖掘 显性特征交叉&#xff1a; 针对的是隐性无脑交叉的DNN的不足&#xff0c; 针对一些重要的关键特征进行显性特征交叉&#xf…

Java中BIO、NIO和AIO的区别和应用场景

IO的方式通常分为几种&#xff0c;同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。 一、BIO 在JDK1.4出来之前&#xff0c;我们建立网络连接的时候采用BIO模式&#xff0c;需要先在服务端启动一个ServerSocket&#xff0c;然后在客户端启动Socket来对服务端进行通信&#…

学习网安需要了解的一些基础知识

P1.基本概念 1.POC/EXP POC(proof of concept)常指一段漏洞验证代码&#xff1b;EXP(exploit)指利用系统漏洞进行攻击的动作 PoC是证明漏洞存在的,而 Exp 是利用这个漏洞进一步进行攻击&#xff0c;先有POC&#xff0c;才有EXP 2.Payload/shellcode payload&#xff0…

【奶奶看了也不会】AI绘画 Mac安装stable-diffusion-webui绘制AI妹子保姆级教程

1.作品图 2.准备工作 目前网上能搜到的stable-diffusion-webui的安装教程都是Window和Mac M1芯片的&#xff0c;而对于因特尔芯片的文章少之又少&#xff0c;这就导致我们还在用老Intel 芯片的Mac本&#xff0c;看着别人生成美女图片只能眼馋。所以小卷这周末折腾了一天&#…

Random(一)高并发问题,ThreadLocalRandom源码解析

目录1.什么是伪随机数&#xff1f;2.Random2.1 使用示例2.2 什么种子重复&#xff0c;随机数会重复&#xff1f;2.3 nextInt() 源码分析2.4 线程安全的实现2.5 高并发问题3.ThreadLocalRandom3.1 使用示例3.2 current() 源码解析3.2.1 Thread中保存的变量&#xff1a;3.2.2 Thr…

2023最新谷粒商城笔记之MQ消息队列篇(全文总共13万字,超详细)

MQ消息队列 其实队列JDK中本身就有&#xff0c;不过这种队列也只能单体服务可能会使用&#xff0c;一旦项目使用的分布式架构&#xff0c;那么一定还是需要用到一个消息中间件的。我们引入消息队列的原因就是对我们的页面相应速度再优化&#xff0c;让用户的体验更好&#xff…

Ae:使用占位符

占位符 Placeholder本质上是一个静止的彩条图像&#xff0c;用来临时代替缺失的素材。自动占位符当 Ae 找不到源素材&#xff0c;比如被移动、删除或重命名&#xff0c;Ae 将自动生成占位符&#xff0c;在项目面板中用斜体显示&#xff0c;使用该素材的任何合成将用一个占位符图…

【R统计】R语言相关性分析及其可视化

&#x1f482; 个人信息&#xff1a;酷在前行&#x1f44d; 版权: 博文由【酷在前行】原创、需要转载请联系博主&#x1f440; 如果博文对您有帮助&#xff0c;欢迎点赞、关注、收藏 订阅专栏&#x1f516; 本文收录于【R统计】&#xff0c;该专栏主要介绍R语言实现统计分析的…

libxlsxwriter簇状柱形图绘制

libxlsxwriter的功能覆盖面很大&#xff0c;今天一起来看一下如何用这个库来生成带有簇状柱形图的表格。 1 簇形柱状图 首先来看一下Excel的样例表格&#xff0c;簇状柱形图往往是用来对比若干“系列”的数据在某一时间段内&#xff0c;或某一情境下的差异情况。在商务领域还…

小白量化《穿云箭集群量化》(4)指标公式写策略

小白量化《穿云箭集群量化》&#xff08;4&#xff09;指标公式写策略 穿云箭量化平台支持中文Python写量化策略&#xff0c;同时也直接支持股票公式指标写策略。下面我们看看是如何实现的。 股票软件的指标公式语法是一样的&#xff0c;不同仅仅是个别函数或绘图函数或绘图命令…

java多态理解和底层实现原理剖析

java多态理解和底层实现原理剖析多态怎么理解java中方法调用指令invokespecial和invokevirtual指令的区别invokeinterface指令方法表接口方法调用为什么不能利用方法表快速定位小结多态怎么理解 抽象事务的多种具体表现&#xff0c;称为事务的多态性。我们在编码过程中通常都是…

计算机网络 第4章 作业1

一、选择题 1. 由网络层负责差错控制与流量控制,使分组按序被递交的传输方式是_________&#xff08;C&#xff09; A&#xff0e;电路交换 B&#xff0e;报文交换 C&#xff0e;基于虚电路的分组交换 D&#xff0e;基于数据报的分组交换 2. TCP/IP 参考…

Bunifu.UI.WinForms 6.0.2 Crack

Bunifu.UI.WinForms为 WinForms创建令人惊叹的UI Bunifu.UI.WinForms我们为您提供了现代化的快速用户界面控件。用于 WinForms C# 和 VB.NET 应用程序开发的完美 UI 工具 简单 Bunifu.UI.WinForms没有臃肿的特征。正是您构建令人惊叹的 WinForms 应用程序所需要的。只需拖放然…

计算机网络高频知识点

目录 一、http状态码 二、强缓存与协商缓存 三、简单请求与复杂请求 四、PUT 请求类型 五、GET请求类型 六、GET 和 POST 的区别 七、跨域 1、什么时候会跨域 2、解决方式 八、计算机网络的七层协议与五层协议分别指的是什么 1、七层协议 2、五层协议 九、计算机网…

监控生产环境中的机器学习模型

简介 一旦您将机器学习模型部署到生产环境中&#xff0c;很快就会发现工作还没有结束。 在许多方面&#xff0c;旅程才刚刚开始。你怎么知道你的模型的行为是否符合你的预期&#xff1f;下周/月/年&#xff0c;当客户&#xff08;或欺诈者&#xff09;行为发生变化并且您的训练…

服务器部署—部署springboot之Linux服务器安装jdk和tomcat【建议收藏】

我是用的xshell连接的云服务器&#xff0c;今天想在服务器上面部署一个前后端分离【springbootvue】项目&#xff0c;打开我的云服务器才发现&#xff0c;过期了&#xff0c;然后又买了一个&#xff0c;里面环境啥都没有&#xff0c;正好出一期教程&#xff0c;方便大家也方便自…

大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——ReduceTask工作机制

1、ReduceTask工作机制 ReduceTask工作机制&#xff0c;如下图所示。 &#xff08;1&#xff09;Copy阶段&#xff1a;ReduceTask从各个MapTask上远程拷贝一片数据&#xff0c;并针对某一片数据&#xff0c;如果其大小超过一定阈值&#xff0c;则写到磁盘上&#xff0c;否则直…

DHTMLX Suite 8.0.0 Crack

适用于现代 Web 应用程序的强大 JavaScript 小部件库 - DHTMLX 套件 用于创建现代用户界面的轻量级、快速且通用的 JavaScript/HTML5 UI 小部件库。 DHTMLX Suite 有助于推进 Web 开发和构建具有丰富功能的数据密集型应用程序。 DHTMLX Suite 是一个 UI 小部件库&#xff0c;用…

指针数组和数组指针的区别

数组指针&#xff08;也称行指针&#xff09;定义 int (*p)[n];()优先级高&#xff0c;首先说明p是一个指针&#xff0c;指向一个整型的一维数组&#xff0c;这个一维数组的长度是n&#xff0c;也可以说是p的步长。也就是说执行p1时&#xff0c;p要跨过n个整型数据的长度。如要…