事件总线这个观点对你来说可能很陌生,但提到不雅察看者(颁布-订阅)模式,你也许就很熟悉。事件总线是对颁布-订阅模式的一种实现。它是一种集中式事件措置惩罚惩罚机制,允许差此外组件之间进行相互通信而又不需要彼此依赖,到达一种解耦的目的。
我们来看看事件总线的措置惩罚惩罚流程:
了解了事件总线的根基观点和措置惩罚惩罚流程,下面我们就来分析下如何去实现事件总线。
2.回归素质在动手实现事件总线之前,我们还是要追本溯源,探索一下事件的素质和颁布订阅模式的实现机制。
2.1.事件的素质我们先来探讨一下事件的观点。都是读过书的,应该都还记得记叙文的六要素:时间、所在、人物、事件(起因、颠末、功效)。
我们拿注册的案例,来解释一下。 用户输入用户名、邮箱、暗码后,点击注册,输入无误校验通过后,注册告成并发送邮件给用户,要求用户进行邮箱验证激活。
这里面就涉及了两个主要事件:
注册事件:起因是用户点击了注册按钮,颠末是输入校验,功效是是否注册告成。
发送邮件事件:起因是用户使用邮箱注册告成需要验证邮箱,颠末是邮件发送,功效是邮件是否发送告成。
其实这六要素也适用于我们措施中事件的措置惩罚惩罚过程。开发过WinForm措施的都知道,我们在做UI设计的时候,从工具箱拖入一个注册按钮(btnRegister),双击它,VS就会自动帮我们生成如下代码:
void btnRegister_Click(object sender, EventArgs e) { // 事件的措置惩罚惩罚 }此中object sender指代发掉事件的东西,这里也就是button东西;EventArgs e 事件参数,可以理解为对事件的描述 ,它们可以统称为事件源。此中的代码逻辑,就是对事件的措置惩罚惩罚。我们可以统称为事件措置惩罚惩罚。
说了这么多,无非是想透过现象看素质:事件是由事件源和事件措置惩罚惩罚构成。
2.2. 颁布订阅模式界说东西间一种一对多的依赖关系,使得每当一个东西转变状态,则所有依赖于它的东西城市得到通知并被自动更新。 ——颁布订阅模式
颁布订阅模式主要有两个角色:
颁布方(Publisher):也称为被不雅察看者,当状态转变时卖力通知所有订阅者。
订阅方(Subscriber):也称为不雅察看者,订阅事件并对接收到的事件进行措置惩罚惩罚。
颁布订阅模式有两种实现方法:
简单的实现方法:由Publisher维护一个订阅者列表,当状态转变时循环遍历列表通知订阅者。
委托的实现方法:由Publisher界说事件委托,Subscriber实现委托。
总的来说,颁布订阅模式中有两个关键字,通知和更新。 被不雅察看者状态转变通知不雅察看者做出相应更新。 解决的是当东西转变时需要通知其他东西做出相应转变的问题。
如果画一个图来暗示这个流程的画,图形应该是这样的:
3 实现颁布订阅模式相信通过上面的解释,对事件和颁布订阅模式有了一个概略的印象。都说理论要与实践相结合,所以我们还是动动手指敲敲代码对照好。 我将以『不雅察看者模式』来垂钓这个例子为根本,通过重构的方法来完善一个越发通用的颁布订阅模式。 先上代码:
/// <summary> /// 鱼的品类枚举 /// </summary> public enum FishType { 鲫鱼, 鲤鱼, 黑鱼, 青鱼, 草鱼, 鲈鱼 }垂钓竿的实现:
/// <summary> /// 鱼竿(被不雅察看者) /// </summary> public class FishingRod { public delegate void FishingHandler(FishType type); //声明委托 public event FishingHandler FishingEvent; //声明事件 public void ThrowHook(FishingMan man) { Console.WriteLine("开始下钩!"); //用随机数模拟鱼咬钩,若随机数为偶数,则为鱼咬钩 if (new Random().Next() % 2 == 0) { var type = (FishType) new Random().Next(0, 5); Console.WriteLine("铃铛:叮叮叮,鱼儿咬钩了"); if (FishingEvent != null) FishingEvent(type); } } }