伪中介模式(5.5)

中介模式(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]中介者模式



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值