程序员人生 网站导航

伪中介模式(5.5)

栏目:互联网时间:2014-09-30 01:54:00

中介模式(mediator pattern)是一种“平台式”或“管家式”委派方式。

中介模式中,中介是各个希望相互交互的参与者的共同且唯一代理,它完成消息的转发或处理。

平台式中介

现实生活中有集市、股票交易所、婚姻介绍所、房屋中介等形形色色的中介(mediator)组织,它们有效地将参与者(participator)的两两交互转化为参与者与中介的交互。但是,这些中介正好是GoF中介模式的错误例子。网上有许多人用QQ为例引入中介模式,显然没有从代码的角度分析,纯属想当然

这里说一个现实的场景。一场Party,有男生/Boy、女生/Girl参加,每个人都可以与其他对象交互。请问,实现这一场景的代码有多复杂?只有当你真正写出代码时,你会发现10万个对象的彼此交谈,也不过两个类的代码要写。

例程 5 9 不需要中介 package delegate.mediator.party; public abstract class Actor{ String name; public abstract void send(String message,Actor to); public abstract void receive(String message,Actor from); } package delegate.mediator.party; import static tool.Print.*; public class Boy extends Actor{ private int count; public Boy(String name){ this.name =name; } @Override public void send(String message,Actor to){ pln(this.name+" To "+to.name+":""+message+"""); to.receive(message,this); } @Override public void receive(String message,Actor from){ char c = (char)(Math.random()*4+'a'); if(c!='b'){ String msg = message+" "+c; send(msg,from); } } } package delegate.mediator.party; public class Party{ public static void main(){ Actor[] alist = new Actor[]{ new Boy("B1"),new Boy("B2"),new Boy("B3"),new Boy("B4"), new Girl("G1"),new Girl("G2"),new Girl("G3") }; for(int i=0;i<alist.length;i++){ int rand= (int)(Math.random()*alist.length); alist[i].send("hi",alist[rand]); } } }

测试代码中,每一个Party参与者发起一次对话,对话的对象是随机的。对话的内容为随机字符,对话必须持续直到随机字符为b(bay)才结束。某一次运行结果(”//结束“不是程序的输出):

B1 To B4:"hi"
B4 To B1:"hi d"
B1 To B4:"hi d d"
B4 To B1:"hi d d a"
B1 To B4:"hi d d a a" //结束
B2 To B3:"hi" //结束
B3 To G2:"hi"//结束
B4 To B1:"hi"//结束
G1 To G2:[hi]
G2 To G1:[hi d]
G1 To G2:[hi d d]
G2 To G1:[hi d d d]
G1 To G2:[hi d d d a]
G2 To G1:[hi d d d a d]
G1 To G2:[hi d d d a d c]
G2 To G1:[hi d d d a d c a]
G1 To G2:[hi d d d a d c a a]
G2 To G1:[hi d d d a d c a a a]
G1 To G2:[hi d d d a d c a a a a]
G2 To G1:[hi d d d a d c a a a a c] //居然聊了这么多 //结束
G2 To B2:[hi]
B2 To G2:"hi c"
G2 To B2:[hi c a]
B2 To G2:"hi c a a"
G2 To B2:[hi c a a a]
B2 To G2:"hi c a a a c"
G2 To B2:[hi c a a a c a]
G3 To G1:[hi]

在讨论中介模式时,许多人看到对象的交互呈现网状结构,几乎每个对象都需要与其他对象发生相互作用。[GoF]中介者模式:“定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互”。事实上,上述代码告诉了一个事实,这里不需要中介模式:

①各对象之间并不需要“显式”持有彼此的引用。Boy和Girl是Actor的子类,即使Party中出现了Boy和Girl等具体类型,Boy和Girl的类体中依赖Actor即可。②多个类(Boy、Girl)的大量对象的交互,并不一定会导致类之间的过度耦合。Boy和Girl之间就不存在任何耦合。类似的,让家长、老师等参加Party,只要他们是Actor,彼此之间不存在任何耦合。

所以,上面的例子并不是我们需要中介(这里不是中介模式)的原因。

然而,如果有一个对象需要找一个女朋友,他一个个地与每一个Girl对象交互,就显得非常低效和不现实。此时,他需要一个能够广播的“平台”。平台式的中介中,不管参与者如何形形色色,中介的作用如同一个公告牌。所以非常容易地联想到观察者模式,事实上,作为公告牌的“中介模式”就是观察者模式

于是,由于中介者Party现在作为交互平台,它被所有感兴趣的参与者观察!再次不同于[GoF]中介者模式。[GoF]中,它写道“将Mediator实现为一个观察者,各Colleague作为Subject”。而此时,我们的代码是:Mediator实现为一个Subject,各Colleague作为Observer。

这一“平台式中介的代码,网上随处可见。

对象和类

[GoF]中介者模式:“定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其耦合性松散..."

这也给我们带来一个问题:这里的”对象“是什么东西

在Java等面向对象的语言中,yqj2065一直强调:类是第一性的。程序员编程针对的都是类而非对象。事实上,[GoF]的中介者模式――“管家式”委派方式中,才体现了一个类(的对象)发生状态改变,将导致许多其他类(的对象)发生相应的变化。和股票交易所、婚姻介绍所等不同,后者虽然参与者有诸多对象,真正的类不多而且交互简单。

有人说了:Party中有的男女对上眼了,会一直聊到Party结束;有的男生可以一直聊篮球;有的女生只和女生聊,有的女生只和名字好听的人聊……你怎么处理这些对象?

还是一句话:我将处理的不是对象而是类――匿名类!你可以用匿名类或λ表达式为客户留下无限的扩展空间。


总之,股票交易所、婚姻介绍所、聊天室的例子,都不是[GoF]中介者模式



------分隔线----------------------------
------分隔线----------------------------

最新技术推荐