.NET 4.0下的观察者模式

ASP.NET实现的观察者模式 我们某个报表界面现在有个dashboard的数据发生变化,需要在它更新的时候去更新此页面上其它几个报表的数据那么可以使用观察者模式来实现。观察者模式有个很好的特点是能够对观察者的add/remve有很大的灵活性 立即下载

.NET 4.0下的观察者模式

下图是一个经典的观察者模式的结构。(图来源于wikipedia)

观察者模式被定义为解决一个对象对多个对象的依赖问题。当一个对象的状态发生改变,它会自动通知其它依赖对象。关于该设计模式的介绍可以更多参考Terrylee的.NET设计模式(19):观察者模式(Observer Pattern)。这篇文章主要介绍在 .NET 4.0 怎么实现观察者模式。

 

在.NET 4.0下位我们提供了两个观察者模式的底层接口:IObservable<T>和IObserver<T>。这两个接口定义如下:

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

 

复制代码
public interface IObserver<in T>
{
    void OnCompleted();
    void OnError(Exception error);
    void OnNext(T value);
}
复制代码

 

IObserable就相当于是传统模式中的Subject,而IObserver就是订阅者。现在来演示一个新闻订阅的实例:当有被订阅的新闻站点有新文章发布时,发送信息通知它的订阅者。

首先定义一个Article类,它就相当于是新闻网站中每一篇文章实体,保存着每篇文章的信息:

复制代码
class Article
{
   public String Title;
   public DateTime Date;
   public String Author;
   public String Content;
}
复制代码

 

然后是我们的订阅源——新闻站点:

复制代码
class News : IObservable<Article>
{
    //用一个list来模拟保存站点中所有的文章
    private List<Article> articles = new List<Article>();
    //保存的所有的订阅者信息
    private List<IObserver<Article>> observers = new List<IObserver<Article>>();

    public IDisposable Subscribe(IObserver<Article> observer)
    {
        if (!this.observers.Contains(observer))
        {
            this.observers.Add(observer);
        }
        return new unsubscribe(observers, observer);
    }

    private class unsubscribe : IDisposable
    {
        private IObserver<Article> _observer;
        private List<IObserver<Article>> _observers;

        public unsubscribe(List<IObserver<Article>> observers, IObserver<Article> observer)
        {
            this._observer = observer;
            this._observers = observers;
        }

        public void Dispose()
        {
            if (this._observers != null && this._observers.Contains(this._observer))
            {
                this._observers.Remove(this._observer);
            }
        }
    }

    //向订阅者发送通知
    private void Notify(Article article)
    {
        foreach (var item in this.observers)
        {
            item.OnNext(article);
        }
    }
    //当有新的文章发布时通知订阅者
    public void AddArticle(Article article)
    {
        this.articles.Add(article);
        this.Notify(article);
    }

}
复制代码

 

下面来定义我们的订阅者。

复制代码
class Person : IObserver<Article>
{
    //订阅者姓名
    String name;
    //保存订阅的新闻站点,方便以后取消订阅
    Dictionary<IObservable<Article>, IDisposable> sbscribes = new Dictionary<IObservable<Article>, IDisposable>();

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

    public void Subscribe(IObservable<Article> news)
    {
        IDisposable unsub = news.Subscribe(this);
        sbscribes[news] = unsub;
    }

    public void UnSubscribe(IObservable<Article> news)
    {
        if (sbscribes.ContainsKey(news))
        {
            sbscribes[news].Dispose();
            sbscribes.Remove(news);
        }
    }

    //没有实现
    public void OnCompleted()
    {
        throw new NotImplementedException();
    }

    //当订阅中出现错误的处理没有实现
    public void OnError(Exception error)
    {
        throw new NotImplementedException();
    }

    //当有新的推送通知到达后的处理
    public void OnNext(Article value)
    {
        Console.WriteLine("One News: {0}",value.Title);
    }
}
复制代码

 

下面我们看下运行时的代码:

复制代码
static void Main(string[] args)
{
    News ChinaNews = new News();
    News EuropeNews = new News();
    Person person1 = new Person("heqichang");
    Person person2 = new Person("Jim");

    //我自己订阅了中国新闻和欧洲新闻
    person1.Subscribe(ChinaNews);
    person1.Subscribe(EuropeNews);
    //Jim订阅了欧洲新闻
    person2.Subscribe(EuropeNews);

    EuropeNews.AddArticle(new Article()
    {
        Title = "New title",
        Date = DateTime.Now.Date,
        Author = "heqichang",
        Content = "New content"
    });

}
复制代码

 

现在我们很多人都应该使用着智能手机,我们可能经常在手机上收到一些应用发来的推送信息,这样的模式就跟我们的观察者模式很像。  

 

扩展阅读:

Reactive Extensions,简称Rx,是以IObserable<T>以及IObserver<T>为核心的,使用LINQ方式编程的.NET扩展库。 Rx = Observables + LINQ + Schedulers。有兴趣的可以搜索一下。

以前我们订阅博客信息,依靠的都是拉文章,现在我们也可以使用“推”的方式来订阅。参看:PubSubHubbub

 

参考链接:

http://msdn.microsoft.com/zh-cn/library/dd783449(v=vs.100).aspx

委托实现观察者模式 用C#委托实现的观察者模式的例子,理解委托订阅回调等等 立即下载

相关推荐

数据中心GPU芯片性能参数速查表(Nvidia+国产算力卡)

本文提供了一份数据中心GPU芯片性能参数速查表,涵盖Nvidia与国产算力卡两大阵营。文章详细解读了算力、显存、互连技术及功耗等关键性能指标,并对比了A100、H100、昇腾910B等主流型号,旨在帮助用户根据AI训练、推理等实际场景,做出高效的硬件选型与成本评估决策。

a0b1c2d3的专栏 836

在.NET中实现观察者模式(3种技术)

目录 介绍 背景 示例场景 实现 观察者模式(在.NET 4.0之前版本) &lt;技术#1&gt; &lt;技术#2&gt; &lt;技术#3&gt; 在.NET中实现观察者模式的多种技术 下载源代码 - 79.8 KB 介绍 我们通过多年的软件开发职业生涯了解了设计模式。在所有模式中,我遇到的最酷和最实用的是观察者模式又叫发布-订阅模式。您将找到有关如何使用框架中提供的程...

寒冰屋的专栏 1638

python音频信号分析

声音以具有诸如频率、带宽、分贝等参数的音频信号的形式表示,典型的音频信号可以表示为幅度和时间的函数

MAY的博客 2785

Rx学习之面向 .NET 和 C# 开发人员的响应式编程 - IEnumerable、IQueryable、IObservable 和 IQbservable 简介

响应式扩展已经存在了一段时间,在这篇文章中,我们应该更详细地讨论反应式扩展。此外,在这篇文章中,我们将触及IQbservables——世界上最神秘的名字/界面,可能是在希格斯玻色子之后。推送和拉取序列无处不在 - 现在设备在一端,云在另一端,大多数数据交易都是通过推/拉序列进行的。因此,必须掌握有关其周围编程模型的基本概念。

Three_ST的博客 1246

Index-TTS-1.5:多模态语音合成的技术演进与商业落地实践

本文深入探讨了Index-TTS-1.5在多模态语音合成领域的技术演进与商业落地。该模型基于GPT风格的自回归Transformer架构,通过优化条件编码器和引入字符-拼音混合建模,显著提升了语音生成的稳定性、精准度和真实感,实现了高质量的零样本语音克隆。文章还详细介绍了其云端体验、本地WebUI部署及ComfyUI集成等实战路径,并分析了其在虚拟数字人、个性化内容创作等商业场景中的应用潜力与挑战。

weixin_29098367的博客 401

C# IObservable与IObserver通知机制 观察者模式(推式模型)

using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace ConsoleApp1 { class Program { static void Main(string[] args) { /* C# I.

深南大道 1081

ISP图像处理Verilog仿真框架搭建(附代码)

基于Verilog的图像处理仿真框架搭建

路漫漫其修远兮,吾将上下而求索 1896

三种观察者模式的C#实现

系列主题:基于消息的软件架构模型演变   说起观察者模式,估计在园子里能搜出一堆来。所以写这篇博客的目的有两点: 观察者模式是写松耦合代码的必备模式,重要性不言而喻,抛开代码层面,许多组件都采用了Publish-Subscribe模式,所以我想按照自己的理解重新设计一个使用场景并把观察者模式灵活使用在其中 我想把C#中实现观察者模式的三个方案做一个总结,目前还没看到这样的总结 现在我们来假设...

weixin_34025151的博客 296

Verilog实战:手把手教你实现四路组相联Cache(附完整代码解析)

本文提供了一份详细的Verilog实战指南,手把手教你实现一个四路组相联Cache。内容涵盖从设计规格、核心存储阵列、LRU替换策略到状态机设计的完整流程,并附有代码解析与优化技巧,旨在帮助硬件设计者掌握Cache控制器的RTL实现与调试方法。

pp12345的博客 516

史上最全!研究生科研必备科研工具(含AI科研工具),附使用说明和示例

这些工具在科研中的应用非常广泛,可以帮助研究生更高效地完成研究任务。为了更好地利用这些工具,建议深入学习它们的官方文档和教程,或者参加相关的工作坊和培训。

智能AI让学术科研更容易 3942

Reactive Extensions 初识

目录: 简介 示例 结论 在.NET 4.0中多了一个IObservable和IObserver接口。用MSDN的话说是:基于推送的通知的提供程序。相当拗口。个人理解就是属性发生变化时,订阅该属性的方法得到通知。就是观察者模式的定义。 示例: 现在有A和B。他们输入值后得到C。只要A和B有一个输入,C就会发生变化。 我用观察者模式来写 A输入了值。C发生了变化: ...

weixin_30566063的博客 202

【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法

相比C文本类编程语言,Simulink图形化编程语言的优势是逻辑思路和数据流清晰了很多,劣势是程序执行的时序不明确,而且各个模块的配置使编程的灵活度下降了不少,在使用习惯上面总感觉有各种限制。本文就是拆解Simulink中最基础的几个编程模块,发扬它的优势,避开劣势。

Mr.Cssust的博客 3849

Observer pattern in JavaScript

The observer pattern (a subset of the asynchronous publish/subscribe pattern) is a software design pattern in which an object, called the subject, maintains a list of its dependents, called ob...

weixin_30336061的博客 100

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

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

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

Reactive Extensions简介一

在.Net 4.0中引入了两个新的接口用来实现观察者模式——IObservable和IObserver。IObservable是数据源,IObserver是观察者,观察者订阅数据源后,当新的数据产生时,将其主动传给所有的订阅者(Iobserver)。 观察者模式比较基础,因此在这里并不多加介绍,没有相关基础的朋友可以参看MSDN的这两个链接。 l Observer(观察器) l 探究观察者...

weixin_33892359的博客 154

VB摄像头监控

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

wxpython 多线程_WxPython 4.0.4多线程访问UI

WxPython 4.0.4多线程访问UI最开始做框架的时候的需求就是多线程访问UI,以前在.NET WPF使用MVVM和数据驱动很容易做到,在JavaSwing中使用另类的观察者模式也实现了。在WxPython中使用观察者模式直接程序崩溃,于是乎仔细的研究了一下发现使用wx.CallAfter()可以实现。首先在类中引入import wxfrom wx.lib.pubsub import pu...

weixin_42530536的博客 180

蓝牙模块HM-10手册

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

wxpython多线程消息传递_WxPython 4.0.4多线程访问UI

WxPython 4.0.4多线程访问UI最开始做框架的时候的需求就是多线程访问UI,以前在.NET WPF使用MVVM和数据驱动很容易做到,在JavaSwing中使用另类的观察者模式也实现了。在WxPython中使用观察者模式直接程序崩溃,于是乎仔细的研究了一下发现使用wx.CallAfter()可以实现。首先在类中引入import wxfrom wx.lib.pubsub import pu...

weixin_39611161的博客 141

制造业ERP系统源码大解析:ASP.NET生产管理系统,基于C#开发,VS2019环境,含基础...

注意GetPendingOrders方法同时加载了供应商和采购明细数据,这种预先加载策略在ERP这种需要频繁关联查询的场景特别重要。作为一款专为生产制造场景设计的通用管理系统,这套代码在功能模块划分和业务逻辑处理上确实有不少值得说道的地方。虽然实际生产场景要考虑设备负载、物料准备等更多因素,但这个基础版本已经体现了制造业排产的核心逻辑——在保交付的前提下优化资源利用率。比如生产管理相关的控制器和视图都集中在Production区域,开发时找对应文件特别方便,比传统MVC的扁平结构更适合大型项目。

CjQYqIyjLwCW的博客 583

ContextMenuManager技术架构深度解析:Windows右键菜单管理系统的实现原理与设计模式

ContextMenuManager是一款基于.NET Framework 4.0开发的Windows右键菜单管理系统,采用分层架构设计和模块化实现,通过Windows注册表API和Shell扩展接口实现对系统右键菜单的全面管理。本文将从技术架构、核心模块、实现细节和应用场景四个维度,深度剖析这一专业级系统管理工具的技术实现原理。 ## 技术架构概览 ### 系统架构设计模式 ContextM

gitblog_00623的博客 161

Reactive Extensions for .NET (Rx)

LINQ to Object使用IEnumerable和IEnumerator两个接口来迭代数据集。枚举器的MoveNext()方法用于从前一个元素枚举到下一个元素,而Current属性则用于检索个别的元素。这种机制采取广泛使用的简洁易懂的"拉(pull)"过程。与之还有一种对应的"推"模式:一个是可以从集合中提取数据,同时可以把数据推进同样的集合。 理论上来说,IEnumerable...

weixin_30606461的博客 75

DotNetGuide委托与事件:.NET中的观察者模式实现

在.NET开发中,对象间的通信往往是系统设计的关键环节。当一个对象状态发生变化时,如何高效通知其他依赖对象?传统的硬编码调用不仅导致紧耦合,更会让代码维护变成一场噩梦。本文将深入解析委托(Delegate)与事件(Event)的底层机制,通过完整实现观察者模式(Observer Pattern),帮助你构建松耦合、高扩展性的.NET应用。读完本文,你将掌握: - 委托类型的声明与多播委托的高级用...

gitblog_00683的博客 419
上一篇: 我为什么喜欢用C#来做并发编程
下一篇: .NET的Actor模型:Orleans Orleans是微软推出的类似Scala Akka的Actor模型,
puppetgg
博客等级 码龄11年 1粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值