冒号课堂§3.4:事件驱动

!预览

  • 它们(同步回调和异步回调)都使调用者不再依赖被调者,将二者从代码上解耦,异步调用更将二者从时间上解耦

  • 它们(控制反转、依赖反转和依赖注射)的主题是控制与依赖,目的是解耦,方法是反转,而实现这一切的关键是抽象接口

  • “回调”强调的是行为方式——低层反调高层,而“抽象接口”强调的是实现方式——正是由于接口具有抽象性,低层才能在调用它时无需虑及高层的具体细节,从而实现控制反转

  • 控制反转导致了事件驱动式编程的被动性

  • 事件驱动式还具有异步性的特征,这是由事件的不可预测性与随机性决定的

  • 独立是异步的前提,耗时是异步的理由

  • 发行/订阅模式正是观察者模式的别名,一方面可看作简化或退化的事件驱动式,另一方面可看作事件驱动式的核心思想

?提问

  • 什么是事件?有哪些不同类型的事件?

  • 什么是回调函数?什么是异步同调?它们有什么用处?

  • 控制反转的目的是什么?它是如何实现的?在框架设计中起什么作用?

  • 控制反转、依赖反转原则和依赖注射的共同点是什么?

  • 事件驱动式编程有哪些关键步骤?

  • 异步过程特点和作用是什么?

  • 事件驱动式编程最重要的特征是什么?它们是如何实现的?

  • 事件驱动式与观察者模式、MVC架构有何关系?

:讲解

逗号渐觉睡虫上脑,开始闭目点头。正神游之际,忽觉腰间一阵酥麻。惺眼微睁,原是被引号的胳膊肘给捅的,顿时警醒。抬头见讲台上的老冒正目光灼灼地盯着自己,不禁脸颊微烫,嗫嚅道:“不好意思,昨晚睡得太晚了。”

冒号却不以为意:“正愁找不到新话题呢,你倒启发我了。话说课堂上睡觉大抵有三种方式——”

话音未落,有人已笑不自禁。

“第一种是警觉式:想睡可又担心被老师发现,不时睁眼查看周围的变化。同时双耳保持警戒,一有异动立刻挺直身板。”冒号有板有眼地形容,“第二种是宽心式:俯桌酣睡,如处无人之境。境界至高者或可雷打不动,或可鼾声如雷。”

“总之是很雷人。”叹号的网络新语再度引发笑声。

冒号继续分析:“第三种是托付式:请人放哨,非急勿扰。遂再无顾忌,大可封目垂耳,安心入眠。请问你们乐意采用哪种方式?”

“第一种方式睡不踏实,不得已而为之。敢用第二种方式的人多半没心没肺,估计IT人都达不到那种境界。只要有同伴在身旁,我想大家都会选第三种方式的。”句号的回答获得一致认同。

冒号续问:“好,抛开第二种方式不谈,为什么第三种要比第一种优越呢?”

句号回答:“犯困者既要打盹又要警戒,必然苦不堪言。如果把警戒的任务委托同伴,两人分工合作,自然愉快得多。”

冒号再问:“他们是如何合作的呢?”

“放哨者一旦发现有情况,立即通知犯困者采取行动——睁眼坐直,作认真听讲状。”句号说得是绘声绘色。

除了两位当事人略显尴尬外,其他人均乐不可支。

眼见时机成熟,冒号不再兜圈:“采用警觉式者主动去轮询(polling),行为取决于自身的观察判断,是流程驱动的,符合常规的流程驱动式编程(Flow-Driven Programming)的模式。采用托付式者被动等通知(notification),行为取决于外来的突发事件,是事件驱动的,符合事件驱动式编程(Event-Driven Programming,简称EDP)的模式。下面我们就来说说这种编程范式。”

逗号瓮声瓮气道:“没想到打瞌睡打出了个范式。”

冒号瞥了他一眼,继续说下去:“为完成一样事,既可以采用流程驱动式,也可以采用事件驱动式。这样的例子在生活中可谓俯拾即是,刚才逗号同学为大家现场示范了一个,谁还能举出其他范例?”

叹号抢先举例:“与客户打交道,推销员主动打电话或登门拜访,他的工作是流程驱动的;接线员坐等电话,他的工作是事件驱动的。”

问号也说:“同样是交通工具,公共汽车主要是流程驱动的,它的路线已预先设定;出租车主要是事件驱动的,它的路线基本上由随机搭载的乘客所决定。”

引号以个人经验作例:“购买喜爱的杂志可以选择频繁光顾报刊亭,也可以选择一次性订阅。浏览关注的新闻网站或博客,可以直接访问站点,也可以订阅相应的RSS。主动检查所关心的内容是否更新是流程驱动的,用订阅的方式是事件驱动的。”

句号回到本行:“Windows下的许多工作既可以在DOS下用批处理程序实现,也可以在图形界面下完成。前者不需人工干预,显然是流程驱动的;后者毫无疑问是事件驱动的。”

“看来你们对这种范式很熟悉嘛。不过,它原理虽简单,威力却无穷。看似一招,实则暗藏百式,甚可幻化千招。个中精妙之处,断非一时可以尽述。”冒号不知不觉中又走进了武侠的世界。

众人听了,暗疑老冒有些言过其实。

冒号正式入题:“首当其冲的问题是:何谓事件?通俗地说,它是已经发生的某种令人关注的事情。在软件中,它一般表现为一个程序的某些信息状态上的变化。基于事件驱动的系统一般提供两类的内建事件(built-in event):一类是底层事件(low-level event)或称原生事件(native event),在用户图形界面(GUI)系统中这类事件直接由鼠标、键盘等硬件设备触发;一类是语义事件(semantic event),一般代表用户的行为逻辑,是若干底层事件的组合。比如鼠标拖放(drag-and-drop)多表示移动被拖放的对象,由鼠标按下、鼠标移动和鼠标释放三个底层事件组成。”

问号推想:“编程人员应该还能创造新的事件类型吧?”

“那是当然。”冒号点点头,“还有一类用户自定义事件(user-defined event)。它们可以是在原有的内建事件的基础上进行的包装,也可以是纯粹的虚拟事件(virtual event)。除此之外,编程者不但能定义事件,还能产生事件。虽然大部分事件是由外界激发的自然事件(natural event),但有时程序员需要主动激发一些事件,比如模拟用户鼠标点击或键盘输入等,这类事件被称为合成事件(synthetic event)[1]。这些都进一步丰富完善了事件体系和事件机制,使得事件驱动式编程更具渗透性。”

叹号嘟哝了一句:“看来这里边还有点名堂。”




本文转自豪情博客园博客,原文链接:http://www.cnblogs.com/jikey/archive/2010/08/03/1791423.html,如需转载请自行联系原作者

上一篇:python之事件驱动与异步IO


下一篇:DevOps系列一:认识事件驱动型计算