今天看了非常给力的《艺龙旅行网架构案例分享》http://www.infoq.com/cn/presentations/jzf-elong-architecture-case-study<wbr>,里面提到了mediator模式。
之前在学习设计模式的时候就注意到了这个模式,现在看了里面的几个应用非常受启发。</wbr>
<wbr><wbr><wbr><wbr>mediator 解决的是多个对象之间关系复杂,连线太多的问题。它的目标就是要减少这些连线的数量,降低复杂度!像不像婚介所,本来我要维护一堆姑娘的联系方式,并还要自己一个个的找(她们也是如此维护和众男伴的关系),ok,现在包办给婚介所就好了。</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr>所以mediator模式的口号是:
<wbr> “给我一个婚介所,就能搞到一群姑娘!”</wbr>
<wbr></wbr>
入题
<wbr></wbr>
在婚介所我们维护的是男女关系,那么在程序当中我们维护也是关系,画在纸上就是各种各样的“连线”,那么有哪几种连线呢?其实可以套用硬件总线的分类方法,当然首先你得连线的对象是谁,就像知道得找怎样的姑娘一样。
1) 数据: 要给什么?可以细为
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>数据的格式,</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
数据的内容
<wbr></wbr>
2) 控制: 怎么给?可以细为
空间上怎么给 -- 调用关系依赖
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> 时间上怎么给 -- 同步的给,还是异步的等</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr></wbr>
3) 地址: 如何找到她?可以细分
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>地址,她在哪?</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>路由,如何找到她?</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr></wbr>
破题
视频当中使用了 i Spring IoC
ii Canonical Data Format 、
iii SOA Enterprise Service BUS。按照上面的分类可以对号入座。
1)数据
最好理解的是数据,对应视频举例ii。
<wbr><wbr> 几个对象之间传递数据,先转化成统一格式,每个对象接收后在转成自己的格式。</wbr></wbr>
<wbr><wbr><wbr><wbr>而对于数据内容,这个类似于数据同步了,其实就是视频当中第一个配置文件分散、更改麻烦的问题。所以引入了一个中心节点,所有的配置文件都从这个节点上抓取。</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr>拿婚介所的例子来说,比如婚介所搞了一个网站,找姑娘?来,先注册,从我这里填写个表(统一的格式)。<wbr>想找什么样的姑娘,看我的公告牌,上面都是待嫁的好姑娘(统一的数据)。啊,阿猫阿狗已经牵手成功了,好好好,赶紧把他们从公告牌当中删除,我们也就看不到了,脑袋里面更不会有(数据的同步),简单不?</wbr></wbr></wbr></wbr></wbr>
<wbr></wbr>
2) 控制
控制的问题其实比较简单,mediator似乎是最想解决这个问题而诞生的。
对于空间上,比如函数func1(), func2(), func3()都分别放在x,y,z文件当中,模块A调用了func1() func2(), B调用了func2(), func3(),C调用了func3(),这里他们之间的调用连线是不是很多。<wbr>如果是把函数func1(), func2(), func3()都写在一个文件当中D, A,B,C只需要知道D, 或者说只需要调用D里面的函数就行了。</wbr>
<wbr></wbr>
视频里面举那个流程改造的例子,我觉得非常的有启发性。里面的改造其实是从原始的状态机 分离成转发流程和处理流程 相互独立的过程。里面时间、空间的解耦都涉及了。
<wbr><wbr><wbr>[1] 原始的状态机涉及到至少3个参数,</wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>A 事件 B当前状态 C下一个状态 = g ( A, B)</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>g 在这里是一个单值函数,给出A,B就有唯一的C对应。一般是通过查一个二维表,</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr> 但是大多情况下是5个参数</wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>A 事件 B当前状态<wbr>C 下一个状态</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> D 对应的处理事件 D = f( A, B )</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> E D的返回结果</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr>所以C呢,修正为C = g( A, B, E ), 或者是 g( A, B,<wbr>f( A, B) ) ,<wbr> -- 其实还是g'(A,B) 嘛,但是从编程的角度我们不考虑这些简化。反过来,我们现在要做的是把f( A, B )从 g( A, B,<wbr>f( A, B) ) 当中分离出去,C变成纯粹的C = g( A, B, E ) ,<wbr>交给全局的状态转换引擎负责。1个</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr> D变成纯粹的D = f( A, B) , 交给当前状态节点的处理函数负责。还是多个</wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr>OK,这样空间上解耦了吧。本质上就是把“当前该干什么”和“下一步是什么”给分离开来,呵呵。尽管对于人脑来说要走一步想三步,但是对电脑来说这样可不见得好。这样的好处是,对于流程节点来说,当业务发生变化的时候,比如上面视频提到的例子,对于VIP来说可以先买票 ==> 再出票 ==> 最后付钱,而一般会员和一次性顾客都得先付钱 ==> 再买票 ==> 最后出票,</wbr></wbr></wbr></wbr>
<wbr>只需要g( A, B, E ) 当中根据B, E 进行再细分,或者增加一个会员状态F,扩展成为 g( A, B, E, F<wbr>) 即可,你可能会说,此时无论如何都要修改g啊,是啊,可是这时候g已经从之前分散在各个节点当中的,被抽取出来放到那一个引擎当中去了,这时候只需要改一处即可!</wbr></wbr>
<wbr><wbr><wbr> 感受到mediator的威力了吧? 婚介所给力不,有木有?<wbr></wbr></wbr></wbr></wbr>
<wbr></wbr>
<wbr><wbr><wbr>[2] 时间上的分离,就更好理解了,即这个调用是异步的,还是同步的。如果是异步的,那么你调用了我,我什么是时候得到结果果再告诉你,你不必死等,是不是时间上分离了?</wbr></wbr></wbr>
<wbr><wbr><wbr> 这个过程发生在哪呢,发生在状态转换引擎得到E的时候,如果是引擎同步等待每个状态节点返回结果,那就没有时间上的分类了。但是视频里面使用了notify-dispatch的模式,就是引擎一个线程T1,维护一个消息队列Q。节点状态处理函数另一个线程T2。 T2就是把处理好的结果放入到Q当中,T1不停的轮询Q,有东西的时候算出来它的下一个状态是什么,然后就分发到下一个状态的节点。这时候因为异步的关系,T1得到E的时候已经丧失上下文了,所以T2最好是返回(A,B,E)
这样一个3元组P。然后T1根据P直接带入到g() 当中得到E。</wbr></wbr></wbr>
<wbr><wbr><wbr><wbr> 时间上的分离的好处我也就不必多说了。</wbr></wbr></wbr></wbr>
还是拿婚介所比喻,
空间上的分离:本来啊,你得漫无目的的在街上寻找姑娘,看到一个性感的背影,好了,空间上接近,迫不及待的想看她正面,然后心开始扑通扑通乱跳。有一句是什么来着,”望背影急刹千军万马“, 你那个兴奋啊,期待啊,可是。。。她一转身,”猛回头喝退各路诸侯“,原来是个如花啊!!!”我的妈呀“。 要是有婚介所就好了,这时候婚介所先帮你过滤了一批,你根本不需要接近这些姑娘鉴别美女。只需要看看婚介所给你的照片。。。(虽然国内PS流行)
时间上的分离:你还不甘心,继续找啊找,好不容易发现了美女,总不能让她这样就走了把,于是你鼓起勇气,厚着脸皮, 要了她的联系方式,心中无比暗爽。 而婚介所事先就帮你要到了一堆美女的联系方式,你只要去找中介即可。这时候对你来说,"找"和"要联系方式" 不是同时进行的。
<wbr></wbr>
3)地址
视频的举例i 和iii 我认为都可归类到这里,为什么呢
i举例是IoC, 解决对象依赖关系,这种依赖关系就是地址,
如A要import com.b.c.d 下的东西,要知道这个com.b.c.d在哪,如何解析这个,是不是地址的问题?
iii举例是SOA当中的Bus,解决对象之间通信的问题,既A要发给B,C,D这些对象,B要发给C, D, E, 但是呢,A, B又不想维护冗余的C,D的地址,这时候怎么办?是不是地址管理和路由的问题?其实学过网络,就知道路由器就是解耦这一过程而发明的。
<wbr><wbr><wbr> 如果说两者一些区别在于后者还一个路由的问题,这个也好办,路由的过程,是不是路由器查找路由表然后把包按照某个地址发出去?好了,路由表也是一个数据型mediator(当然实际当中,每个路由器维护的路由表是不一样的,但是这里只考虑由一个路由器连接而组成的局域网),ok,现在这个路由表原来需要A,B,C,D 各种维护一份,现在好了,由这个数据由路由器来维护了一张公共的表,呵呵。</wbr></wbr></wbr>
相当于你去相亲,不需要事先知道每个姑娘住哪,她们也不需要知道你的,到了婚介所都会一一提供。
<wbr><wbr><wbr> 连这个找路的路由算法都集中在路由器当中了,不需要每个节点都维护一份了。</wbr></wbr></wbr>
相当婚介所服务很到位,怎么去到姑娘家事先用google map 查了一份存好,你也不用自己在费脑筋、费时间去查了。每位姑娘来你家也是如此, 什么,来我家。。。。。
<wbr></wbr>
结题
<wbr></wbr>
<wbr><wbr><wbr><wbr> 所以一旦遇到”连线“数量增多的问题,使用mediator是一个好办法,</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr> 如何分解这个问题,按照数据/控制/地址的方法分类,想想婚介所的例子,相信都能解决的。</wbr></wbr></wbr></wbr>
但是mediator也有个明显的缺陷,就是作为mediator的中心节点 单点失效的问题,这个就不在本篇讨论之列了
一点愚见,敬请指教!转载请注明作者和出处,谢谢!
相关推荐
中介者模式(Mediator) 用意:用一个中介对象来封装一系列对象间的交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互。
C#面向对象设计模式 (行为型模式) Mediator 中介者模式 视频讲座下载
C++设计模式课件17_Mediator_中介者.pdf
中介者模式的完整代码。 程序默认使用vs开发。其他开发工具可能需要做少许调整。
C#面向对象设计模式纵横谈(17):(行为型模式) Mediator 中介者模式
<!-- TOC --> - 23种设计模式 ... - 中介者模式(Mediator) - 访问者模式(Visitor) - 命令模式(Command) - 解释器模式(Interpreter) - 迭代器模式(Iterator) - 备忘录模式(Memento) - 状态模式(S
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
Mediator.rarMediator.rarMediator.rar中介者设计模式
设计模式精解- GoF 23 种设计模式解析附 C++实现源码 目 录 0 引言 ...........................................................................................................................................
中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
C#面向对象设计模式纵横谈(17):(行为型模式) Mediator 中介者模式 (Level 300)
中介者模式(Mediator Pattern)是一种行为型设计模式,用于减少对象之间的直接相互依赖,使得对象间的交互通过一个中介者对象来进行协调。在中介者模式中,对象之间不再直接相互调用,而是通过中介者对象来传递消息...
设计模式精解-GoF 23 种设计模式解析附 C++实现源码 目 录 0 引言 ............................................................................................................................................
设计模式精解-GoF 23种设计模式解析附C++实现源码 目 录 0 引言.........................................................................................................................................
Mediator 中介者模式 若有问题,烦请指出。
一种基于Mediator设计模式的车载多媒体系统设计,宋飞,郭文明,如今,车载多媒体系统已经在汽车产业发展中扮演了越来越重要的角色,而车载系统的设计方式也必将受到越来越多的重视。本文从系统
这是一个运用了中介者设计模式的登录对话框练习题。 该案例改编自结城浩《设计模式-java语言中的应用》一书。 This is a program about a login dialog, wich try to illustrate the design pattern of Mediator. ...
0.1设计模式解析(总序).....................................................................................................2 0.2设计模式解析后记..........................................................
php /** * 中介者模式 * * 用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用从而使其耦合松散,而且可以独立地改变它们之间的交互 */ abstract class Mediator { abstract public function send($...
0.1 设计模式解析(总序)...............2 0.2 设计模式解析后记.......................2 0.3 与作者联系..................................5 1 创建型模式.............................................5 ...