在《JavaScript设计模式》关于中介者模式的介绍里,里面有些错误和擅自添加的例子,虽然例子(英文版没有)是为了让人更好理解,但是该篇章加上的例子却给人误导的感觉,所以如果有人读这个章节时,建议看英文版。
在看这个模式时候,我只想弄明白一点,中介者模式与订阅/发布模式的区别在哪?
中介者模式定义
中介者作为一种行为设计模式,它公开一个统一的接口,系统的不同对象或组件可以通过该接口进行通信。增加一个中介者对象后,所有的相关对象通过中介者对象来通信,而不是互相引用,所以当一个对象发生改变时,只需要通知中介者对象即可。
英文版:
When it comes to the Mediator and Event Aggregator patterns, there are some times where it may look like the patterns are interchangeable due to implementation similarities. However, the semantics and intent of these patterns are very different.
And even if the implementations both use some of the same core constructs, I believe there is a distinct difference between them. I also believe they should not be interchanged or confused in communication because of the differences.
中文版:
它也可能被认为是额外的或者是用于应用程序间的通知,如不同子系统之间的通信,这些子系统本身就很复杂,且可能希望通过发布/订阅关系实现内部组件间的解耦。
我:
首先我是不明白译者为什么不按英文版翻译,另外还有一点译文的意思根本就不是英文版的意思,我觉得不对。
我觉得是——中介者模式与事件订阅模式有些时候看起来是可以互相替换的,因为它们的实现都差不多,但从语义和意图上讲,这些模式是各不相同的。即便是实现都用了相同的核心结构,我相信他们之间还是有区别,在通信时是不能互换和混淆。
PS:总结就是,两个模式实现上有些相同,但意图是不同的。
例子
简述:
机场交通控制系统。控制塔处理飞机的起飞和降落,所有的通信都是控制塔控制的。
代码:
//飞机 var Plane = function(name){ this.name = name; } Plane.prototype.takeOff = function(){ //起飞 ControlTower.takeOff(this); } Plane.prototype.sendMsg = function(toPlane, msg){ //飞机间发消息 ControlTower.sendMsg(this, toPlane, msg); } Plane.prototype.receive = function(fromPlane, msg){ console.log(this.name + "-收到来自-" + fromPlane.name + "消息:" + msg); } //飞机控制塔(中介者) var ControlTower = (function(){ //假设只有一条跑道,跑道只能起飞一只飞机(不说降落) var onTrackPlaneName, canTrackUse = true; var takeOff = function(plane){ if(!canTrackUse){ console.log("跑道正在使用中..."); return; } if(onTrackPlaneName == plane.name){ console.log("您正在起飞中..."); return; } canTrackUse = false; onTrackPlaneName = plane.name; console.log(plane.name + "正在起飞中..."); setTimeout(function(){ canTrackUse = true; onTrackPlaneName = null; console.log(plane.name + "已起飞..."); }, 5000); } var sendMsg = function(from ,to , msg){ to.receive(from, msg); } return { takeOff : takeOff, sendMsg : sendMsg } })(); var p747 = new Plane(‘波音747‘); var p666 = new Plane(‘飞豹666‘); p747.takeOff(); p666.takeOff(); p747.sendMsg(p666, ‘开完飞机吃个饭么‘);
适用场景
1. 一组定义良好的对象,现在要进行复杂的通信。
2. 定制一个分布在多个类中的行为,而又不想生成太多的子类。
可以看出,中介对象主要是用来封装行为的,行为的参与者就是那些对象,但是通过中介者,这些对象不用相互知道。(迪米特法则的具体实现)
优点
1. 中介者模式能够将系统中对象或组件之间所需的通信渠道从多对多减少到多对一。
2. 符合迪米特原则。
迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),就是说一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。
缺点
1. 中介者模式的缺点是显而易见的,因为这个“中介“承担了较多的责任,所以一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。
中介者模式与观察者模式差异
1. 调度中心不同。
中介者模式调度是由中介者,而观察者模式调度的是观察者;
中介者模式与订阅/发布模式的调度方式更像,都是独立一个集中的调度中心。
2. 中介者模式参与了对象行为的实现(例如上面示例的飞机起飞),而观察者模式并不参与,仅做目标通知。
中介者模式与订阅/发布模式差异
1. 中介者模式与业务相关,订阅/发布模式与业务无关。(这是我觉得最大差别)
虽然实现结构非常相像,但是很明显的是,中介者模式参与业务相关东西,所以内容是大相径庭的。
2. 两个模式都有集中调度效果,对象之间不直接参与通信。
参考文献
1. 《Learning JavaScript Design Patterns》 by Addy Osmani
https://addyosmani.com/resources/essentialjsdesignpatterns/book/
2. 《JavaScript设计模式》by 徐涛【译】
本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。
本文地址 :http://www.cnblogs.com/lovesong/p/5575594.html