前言

主要讲的是发布与订阅在Event中的一个简单实现用来加深理解。

C #中的事件(Event)的理解:

事件具有以下属性:(From Events)

  • 发行者确定何时引发事件;订户确定对事件作出何种响应。
  • 一个事件可以有多个订户。 订户可以处理来自多个发行者的多个事件。
  • 没有订户的事件永远也不会引发。
  • 事件通常用于表示用户操作,例如单击按钮或图形用户界面中的菜单选项。
  • 当事件具有多个订户时,引发该事件时会同步调用事件处理程序。 若要异步调用事件,请参阅 Calling Synchronous Methods Asynchronously
  • 在 .NET Framework 类库中,事件基于 EventHandler 委托和 EventArgs 基类。

发布与订阅(Observer, Publish-Subscribe)

意图:

 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并主动更新。解耦

别名: 依赖(Dependents),发布-订阅(Publish-Subscribe)

 Observer模式描述了如何建立这种关系。这一模式中的关键对象是目标(Object)和观察者(observer)。一个目标可以有任意数目的依赖它的观察者。一旦目标的状态发生改变,所有的观察者都得到通知。作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步。

 这种交互也称为 发布-订阅。目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者。可以有任意数目的观察者订阅并接收通知。

发布与订阅的实践

假设一个这样的场景。车类,以及乘客类

车类里:有一个事件,开车通知。有一个方法,开车。

调用开车方法时,通知订阅了开车通知的观察者,然后开车。

首先是定义一个车类:

using System;

namespace EventDemo {
public class MyCar {
//定义一个 上车 的委托
public delegate void BeginOnCarHandler (); //定义一个 上车 委托方法的事件
public event BeginOnCarHandler CarNotification; public string Name { get; set; } public void RunCar () {
CarNotification ();
Console.WriteLine ("好的,都上车了司机" + Name + ",开车了");
}
}
}

然后定义一个乘客类:

namespace EventDemo {
public class Passenger { public string Name { get; set; } public void BeginToCar () {
System.Console.WriteLine ("我上车了,我是:" + Name);
}
}
}

最后执行:

MyCar benz = new MyCar { Name = "Benz" };

            Passenger p4 = new Passenger { Name = "xiaoming" };
Passenger p2 = new Passenger { Name = "xiaohong" }; benz.CarNotification += new MyCar.BeginOnCarHandler(p2.BeginToCar);
benz.CarNotification += new MyCar.BeginOnCarHandler(p4.BeginToCar); benz.RunCar ();

最后的结果为

上面的方法

benz.CarNotification += new MyCar.BeginOnCarHandler(p2.BeginToCar);

也可以改成

benz.CarNotification += p2.BeginToCar;

上面就是一个简单的发布/订阅的例子,在EventBus中也有其涉及的地方,正好可以了解记录一下。

今天下午又仔细思考了一下,更新了一下实例,如下:

一个车,是被观察者,也就是目标 object,它有一个事件,暂且叫它 发车事件。以及观察者 乘客类。

修改了一下Event代码:

using System;

namespace EventDemo {
public class MyCar {
//定义一个 上车 的委托
public delegate void CarHandler (MyCar car); //定义一个 上车 委托方法的事件
public event CarHandler CarNumberNotification; public string Name { get; set; } public int Count { get; set; } public void RunCar () {
Console.WriteLine ($"好的,准备上车了,车名为:{Name},车上人数:{Count}");
if (CarNumberNotification != null) {
CarNumberNotification (this);
}
Console.WriteLine ($"The people now is:{Count}");
}
}
}
namespace EventDemo {
public class Passenger { public string Name { get; set; } public void BeginToCar (MyCar car) {
car.Count++;
System.Console.WriteLine ($"我上车了,我是:{Name},我坐的车是{car.Name}");
}
}
}
            MyCar benz = new MyCar { Name = "Benz" };

            Passenger p1 = new Passenger { Name = "xiaoming" };
Passenger p2 = new Passenger { Name = "xiaohong" }; benz.CarNumberNotification += p1.BeginToCar;
benz.CarNumberNotification += p2.BeginToCar; benz.RunCar ();

这样编写代码更加容易理解一些。

Event 发布与订阅(一)的更多相关文章

  1. Angular 个人深究(二)【发布与订阅】

    Angular 个人深究(二)[发布与订阅] 1. 再入正题之前,首先说明下[ 发布与订阅模式](也叫观察者模式) 1) 定义:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个 ...

  2. node.js 中 events emitter 的实现(发布、订阅模式)

    const EventEmitter = require('events'); const myEmitter = new EventEmitter(); myEmitter.on('event', ...

  3. (转)SqlServer 数据库同步的两种方式 (发布、订阅),主从数据库之间的同步

    最近在琢磨主从数据库之间的同步,公司正好也需要,在园子里找了一下,看到这篇博文比较详细,比较简单,本人亲自按步骤来过,现在分享给大家. 在这里要提醒大家的是(为了更好的理解,以下是本人自己理解,如有错 ...

  4. (原)3.2 Zookeeper应用 - 数据的发布与订阅

    本文为原创文章,转载请注明出处,谢谢 数据的发布与订阅 1.应用 服务端监听数据改变,客户端创建/更新节点数据,客户端提供数据,服务端处理 2.原理 客户端监控节点数据改变事件(例如配置信息,下图的c ...

  5. MSSQL复制中的发布与订阅

    准备条件 1.2台服务器 2.WINDOWS SERVER 2008 64bit + 3.SQL SERVER 2008 R2 + 4.MSSQLSERVER服务与MSSQLAGENT服务正常运行中 ...

  6. 知方可补不足~SQL2008中的发布与订阅模式

    回到目录 作用:完成数据库与数据库的数据同步 原理:源数据库发布需要同时的表,存储过程,或者函数:目标数据库去订阅它,当源发生变化时,目标数据库自己同步,注意,由于这个过程是SQL自动完成的,所以要求 ...

  7. RabbitMQ官方中文入门教程(PHP版) 第三部分:发布/订阅(Publish/Subscribe)

    发布/订阅 在上篇教程中,我们搭建了一个工作队列.每个任务之分发给一个工作者(worker).在本篇教程中,我们要做的之前完全不一样——分发一个消息给多个消费者(consumers).这种模式被称为“ ...

  8. 【SQL Sever】实现SQL Sever的发布。订阅。 双机热备

    实现SQL Sever的发布和订阅  最大的好处就是: 可以实现读写分离,增删改操作在主数据库服务器上进行,查询在备份数据库服务器上进行.一方面提高软件执行效率,另一方面也减轻主库压力. 本次实现发布 ...

  9. Redis - 发布和订阅

    一.概述 1). 发布和订阅是一种消息通信模式. 2). 优点:使消息订阅者和消息发布者耦合度降低,类似设计模式中的观察者模式. 二.发布和订阅 订阅命令: // 订阅一个或多个频道 // 返回值:v ...

随机推荐

  1. C#/AutoCAD 2018/ObjectArx/二次开发添加删除实体的工具函数(四)

    1.添加删除实体 C# ObjectARX二次开发添加删除实体是非常容易主要代码如下: 添加实体: objId = btr.AppendEntity(entity); trans.AddNewlyCr ...

  2. 使用IDEA配置Maven + SpringMVC + Mybatis 【一步一步踩坑详细配置完成】

    PS:初学,想使用Maven配置一个SpringMVC的开发环境,照着网上的各种图文解说,配置了好久都没成功,有些写的不够详细,有些只有写一半,走了不少弯弯绕绕,踩了不少的坑,此文将正确配置成功的步骤 ...

  3. 网络1712--c语言第一次作业总结

    1.作业亮点 1.1大家均能较为独立自主地完成第一次c语言作业,无明显抄袭现象 1.2 以下几位同学博文写的较为优秀,可作为范例供大家参考 田亚琴--态度端正,及时回复评论并及时完善修改博文 戴洁-- ...

  4. Build to win--来自小黄衫

    写在前面 首先非常荣幸.非常侥幸能以微弱的优势得到这次小黄衫,感谢各位老师同学的帮助,也谢谢来自<构建之法>团队的小黄衫赞助! 这次能够获得小黄衫,就像汪老师上课说的那样,其实,是一个积累 ...

  5. oracle删除某个用户所有表(转)

    1. select   'Drop   table   '||table_name||';'             from   all_tables           where   owner ...

  6. Web前端性能分析

    Web前端性能通常上代表着一个完全意义上的用户响应时间,包含从开始解析HTML文件到最后渲染完成开始的整个过程,但不包括在输入url之后与服务器的交互阶段.下面是整个过程的各个步骤: 开始解析html ...

  7. 阿里云CentOS部署小笔记

    快毕业了,我用近两周的时间完成了一个nodeJs+Vue-Cli+Mysql的毕业设计,到了部署的时候了. 然而,博主使用Linux的经验有限得很,所以只能自己慢慢地填坑了. 一.准备工作 1)阿里云 ...

  8. 利用封装、继承对Java代码进行优化

    注:本文实例分别可以在oldcastle(未优化的代码)和newcastle(优化后的代码)中查看,网址见文末 城堡游戏: 城堡中有多个房间,用户通过输入north, south, east, wes ...

  9. 到底什么是 "method group"

    class Program { delegate void NoParam(); delegate void WithOneParam(string name); static void Main(s ...

  10. Python内置函数(34)——filter

    英文文档: filter(function, iterable) Construct an iterator from those elements of iterable for which fun ...