004.可观察对象与观察者

Rx非常适合事件驱动的应用程序。这是有意义的,因为事件(作为)(如前所述)是创建时变值的命令式方法。从历史上看,事件驱动编程主要出现在客户端技术中,因为作为事件实现的用户交互。例如,你可能工作过使用OnMouseMove或OnKeyPressed事件。正因如此,难怪你看到许多使用Rx的客户端应用程序。此外,一些客户端框架是基于Rx,如ReactiveUI (http://reactiveui.net)。

但是让我向您保证,Rx不是仅限客户端的技术。相反,服务器端代码的许多场景都非常适合Rx。另外,就像我说的在此之前,Rx用于大型应用程序,如Microsoft Cortana、Netflix和使用Microsoft StreamInsight的复杂事件处理(CEP)。Rx是一个优秀的库处理应用程序接收消息,而不管它在服务层或客户端层上运行。

接下来介绍什么是可观察对象。可观察对象(Observables)用于实现时变值(我们定义为可观察对象)序列)在Rx。它们代表推送模型( push model ),在该模型中,新数据被推送到(或)通知)观察者。

可观察对象被定义为事件(或通知)的来源,或者,如果你愿意,也可以定义为数据流的发布者。推送模型意味着,不是让观察者从源中获取数据,而是在数据可用时将其传递给观察者,并总是检查是否有尚未获取的新数据(拉取模型)。

Observable实现IObservable接口,该接口位于.NET4.0的System空间里。

public interface IObservable<T>
{IDisposable Subscribe(IObserver<T> observer); 
}

IObservable接口只有一个方法Subscribe,它允许观察者订阅通知。Subscribe方法返回一个Disposable对象,该对象表示订阅,并允许观察者通过调用Dispose方法随时取消订阅。Observables保存订阅的观察者的集合,并在有值得通知的事情时通知他们。这是使用IObserver<T>接口完成的,该接口也位于.NET4.0的System命名空间。如图所示。

public interface IObserver<T>
{void OnNext(T value); void OnError(Exception error); void OnCompleted(); 
}

使用IObservable和IObserver的基本流程如图1.6所示。可观察对象并不总是完整的;它们可以是可能无限数量的序列元素(例如无限集合)的提供者。一个可观察对象也可以是“安静”,意思是它从来没有推动过任何元素,也永远不会。可观察对象也可以失败;失败可以发生在可观察对象已经推送了元素之后,也可以在没有任何元素被推动的情况下发生。

这个可观察的代数用下面的表达式形式化(其中*表示零次或多次,?表示零或一次,且“|”为“或”运算符):
在这里插入图片描述
图1.6是被观察者与观察者交互流程。在这个场景中,观察者被订阅到可观察对象应用程序;可观察对象向观察者“推送”三条消息(只有一条)在这种情况下),然后通知观察者它已经完成。

当失败时,将使用OnError方法通知观察器,并使用异常对象将被传递给观察者进行检查和处理(参见
图1.7)。在出现错误之后(以及在完成之后),将不会有更多的消息推给观察员。当观察者不提供错误处理程序时,Rx使用的默认策略是升级异常并导致崩溃。您将在第10章学习如何优雅地处理错误。
在这里插入图片描述
图1.7在可观察对象中出现错误的情况下,观察者将通过带有异常对象的OnError方法得到通知。

观察者设计模式

在某些编程语言中,事件有时作为一等公民提供,这意味着您可以使用所提供的语言定义和注册事件关键字和类型,甚至将事件作为参数传递给函数。
对于不支持事件作为一等公民的语言,使用观察者模式是一个有用的设计模式,允许您向应用程序添加类似事件的支持。此外,.NET的事件就是基于这种模式现实的。
观察者模式是由Gang of Four (GoF)在《设计模式》中引入的:
可重用的面向对象软件的要素(Addison-Wesley Professional, 1994)。该模式定义了两个组件:主体和观察者(不要混淆)(Rx的观察者)。观察者是对事件感兴趣的参与者将自身订阅到引发事件的主题。这是它在统一中的样子建模语言(UML)类图:
在这里插入图片描述
观察者模式很有用,但有几个问题。观察者只有一个方法来接受事件。如果要附加到多个主题或多个
除了一个事件,您还需要实现更多的更新方法。另一个问题是该模式没有指定处理错误的最佳方法,如果有的话,要由开发人员自己寻找通知错误的方法。最后要解决的问题是如何知道主题什么时候完成,Rx IObservable和IObserver基于Observer设计模式,但对其进行了扩展以解决这些问题的缺点。

——未完待续

译者:重庆教主 20240513

网站:WPF中文网 wpfsoft.com

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

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

相关文章

“智慧食堂”|基于Springboot+vue的“智慧食堂”系统(源码+数据库+文档)

“智慧食堂”系统 目录 基于Springbootvue的“智慧食堂”系统 一、前言 二、系统设计 三、系统功能设计 1功能页面实现 2系统功能模块 3管理员功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍…

缩短项目周期:SOLIDWORKS Electrical简化了电气设计过程

在现代工业设计领域&#xff0c;电气系统设计的复杂性日益增加&#xff0c;然而&#xff0c;达索系统SOLIDWORKS Electrical软件的出现为这一挑战提供了高效的解决方案。该软件支持工程师通过选配的方式快速设计原理图&#xff0c;这极大地简化了电气设计过程&#xff0c;并有效…

形位公差Overview of GDT

零件公差产生于十九世纪后期&#xff0c;其初衷是为了保证零件的互换性。起初只有尺寸公差。由于 当时的设计部门和制造部门通常都在一起或就在隔壁&#xff0c;因此交流起来非常方便。在当时&#xff0c;给 定的公差一般都很大&#xff0c;因此当时的设备刀具的能力对于保证产…

Spring:@Async注解使用注意事项及九大失效场景

前言 原文作者&#xff1a;微信公众号&#xff1a;苏三说技术 场景举例 代码案例 点击此处可观看&#xff1a;Async注解使用注意事项及九大失效场景

Python修改exe之类的游戏文件中的数值

文章目录 场景查找修改 补充字节to_bytes 场景 某些游戏数值&#xff08;攻击力、射程、速度…&#xff09;被写在exe之类的文件里 要先查找游戏数值&#xff0c;然后修改 查找 首先&#xff0c;要查找数值&#xff0c;大数重复较少&#xff0c;建议从大数找起 F 游戏原件…

OPT系列极速版远距离光数据传输器|光通讯传感器安装与调试方法

OPT系列极速版远距离光数据传输器|光通讯传感器使用红外激光通信&#xff0c;满足全双工 100M 带宽&#xff0c;通讯距离可达 300 米。能够快速&#xff0c;稳地传送数据&#xff0c;支持主流的工业控制总线&#xff08;Profinet&#xff0c;Ethercat 等&#xff09;&#xff1…

【JVM】从可达性分析,到JVM垃圾回收算法,再到垃圾收集器

《深入理解Java虚拟机》[1]中&#xff0c;有下面这么一段话&#xff1a; 在JVM的各个区域中&#xff0c;如虚拟机栈中&#xff0c;栈帧随着方法的进入和退出而有条不紊的执行者出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的&#xff08;尽管在…

【RAG 论文】BGM:为 LLM 和 Retriever 的偏好 gap 搭建一个 Bridge

论文&#xff1a;Bridging the Preference Gap between Retrievers and LLMs ⭐⭐⭐ Google Research, arXiv:2401.06954 论文速读 LLM 与 Retriever 之间存在一个 preference gap&#xff1a;大多数 retriever 被设计为 human-friendly&#xff0c;但是 LLM 的偏好与人类的却…

长难句打卡 5.13

And in Europe, some are up in arms over a proposal to drop a specific funding category for social-science research and to integrate it within cross-cutting topics of sustainable development. 在欧洲&#xff0c;有些人正竭力反对一项“终止专用于社会科学研究的…

网络安全防护:抵御DDoS和CC攻击

在当今数字化时代&#xff0c;网络安全已成为任何组织或个人不可忽视的重要议题。DDoS&#xff08;分布式拒绝服务&#xff09;攻击和CC&#xff08;命令与控制&#xff09;攻击作为两种最为常见的网络攻击方式&#xff0c;给网络运营者和用户带来了巨大的威胁和影响。本文将介…

函数memcpy的实现及详解

前言 今天我们来了解一下memcpy函数和它的作用吧&#xff0c;咋们之前已经熟悉了strcpy的使用&#xff0c;它的作用是字符串的拷贝&#xff0c;那么当我们要拷贝其他类型的数据时&#xff0c;应该使用什么函数呢&#xff0c;我们今天给大家介绍的就是memcpy函数&#xff0c;他可…

C++语言的字符数组

存放字符数据的数组是字符数组&#xff0c;字符数组中的一个元素存放一个字符。字符数组具有数组的共同属性。 1. 声明一个字符数组 char c[5]; 2. 字符数组赋值方式 &#xff08;1&#xff09;为数组元素逐一赋值 c[0]H c[1]E c[2]L c[3]L c[4]O &#xff08;2&…

三极管 导通条件

一、三极管理解 三极管是电子行业常用的元器件之一&#xff0c;他是一种电流型控制的器件&#xff0c;他有三种工作状态&#xff1a;截止区&#xff0c;放大区、饱和区。当三极管当做开关使用时&#xff0c;他工作在饱和区。下面简短讲解三极管作为开关使用的方法&#xff0c;只…

2.三极管

2.习题 3.知识补充

Web 安全 PHP 代码审查之常规漏洞

前言 工欲善其事&#xff0c;必先利其器。我们做代码审计之前选好工具也是十分必要的。下面我给大家介绍两款代码审计中比较好用的工具。 一、审计工具介绍 PHP 代码审计系统— RIPS 功能介绍 RIPS 是一款基于 PHP 开发的针对 PHP 代码安全审计的软件。 另外&#xff0c;…

Spring Cloud 概述及项目创建

本篇主要介绍什么是Spring Cloud&#xff0c;以及Spring Cloud工程的创建 目录 一、什么是微服务&#xff1f; 集群 分布式 微服务 二、Spring Cloud 什么是Spring Cloud Spring Cloud 版本 Spring Cloud实现方案 Spring Cloud 工程创建 创建父工程 创建子工程 一、…

MySQL 大量数据插入优化

效率最好的方式是&#xff1a;批量插入 开启事务。 1、数据批量插入相比数据逐条插入的运行效率得到极大提升&#xff1b; ## 批量插入 INSERT INTO table (field1, field12,...) VALUES (valuea1, valuea2,...), (valueb1, valueb2,...),...;当数据逐条插入时&#xff0c;每…

C++类细节,反汇编,面试题02

文章目录 2. 虚函数vs纯虚函数3. 重写vs重载vs隐藏3.1. 为什么C可以重载&#xff1f; 4. struct vs union4.1. 为什么要内存对齐&#xff1f; 5. static作用6. 空类vs空结构体6.1. 八个默认函数&#xff1a;6.2. 为什么空类占用1字节 7. const作用7.1 指针常量vs常量指针vs常量…

【SRC-CPP-OpenCV】给图片更换背景色

文章目录 Part.I IntroductionPart.II Main_bodyChap.I 源码简析Chap.II 效果展示 Part.III 源码Reference Part.I Introduction 本文将介绍如何用 OpenCV 更换图片的背景色&#xff08;附有完整代码&#xff09;。 Part.II Main_body Chap.I 源码简析 配置部分&#xff1a…

1-3ARM_GD32点亮LED灯

简介&#xff1a; 最多可支持 112 个通用 I/O 引脚(GPIO)&#xff0c;分别为 PA0 ~ PA15&#xff0c;PB0 ~ PB15&#xff0c;PC0 ~ PC15&#xff0c;PD0 ~ PD15&#xff0c;PE0 ~ PE15&#xff0c;PF0 ~ PF15 和 PG0 ~ PG15&#xff0c;各片上设备用其来实现逻辑输入/输出功能。…