一雨田的专栏

伟人将复杂的事情变简单,小人将简单的事情变复杂

用户操作
[即时聊天] [发私信] [加为好友]
一雨田ID:dylgsy
91678次访问,排名1090,好友2人,关注者13人。
一雨田
dylgsy的文章
原创 41 篇
翻译 1 篇
转载 6 篇
评论 292 篇
最近评论
heray818:我的邮箱是:heray818@126.com
heray818:你好 能否也传我一份 谢谢了啊
救援隊募集:アダルトエロ不倫
モテ度審査員:童貞セフレナンパ
temp:很好
文章分类
收藏
    相册
    好友Blog
    圈内朋友
    sankt的专栏
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 设计模式简单代码之Mediator模式(二)收藏

    新一篇: UML类图关系全面剖析 | 旧一篇: 设计模式简单代码之Mediator模式(一)

    上一篇用一个例子程序来说明程序中可能会出现的类间关系过于复杂,而导致程序的结构变差的情况。这一章的目的就是说明如何使用Mediator模式来解决这个问题。

    在看实际的代码之前,我们先了解一下为什么Mediator模式能够解决这些问题。问题的所在就是类之间被互相引用而导致混乱,这显然就是多对多的关系(这就是Mediator使用的语境),我们要解决混乱,就要把他们的关系简化为一对多的关系。充当这个角色的就是Mediator。就好象一班人在打架,你打我,我打你,场面十分混乱,这个时候出来一个人为他们做调解,这个人就是我们的Mediator了。:)

    好了,我们首先在程序中写一个Mediator的类:

    // Mediator.H

    #ifndef _MEDIATOR_H
    #define _MEDIATOR_H

    class A;
    class B;
    class C;

    class Mediator
    {
    public:
        Mediator(A 
    *a, B *b, C *c);
        
        
    void ACallB();
        
    void ACallC();

        
    void BCallA();
        
    void BCallC();

        
    void CCallA();
        
    void CCallB();

    private:
        A 
    *_a;
        B 
    *_b;
        C 
    *_c;
    }
    ;

    #endif

    // Mediator.CPP
    #include <iostream>
    using namespace std;

    #include 
    "a.h"
    #include 
    "b.h"
    #include 
    "c.h"

    #include 
    "Mediator.h"

    Mediator::Mediator(A 
    *a, B *b, C *c)
    {
        _a 
    = a;
        _b 
    = b;
        _c 
    = c;    
    }


    void Mediator::ACallB()
    {
        cout 
    << "A call ";
        _b
    ->Function();
    }


    void Mediator::ACallC()
    {
        cout 
    << "A call ";
        _c
    ->Function();
    }


    void Mediator::BCallA()
    {
        cout 
    << "B call ";
        _a
    ->Function();
    }


    void Mediator::BCallC()
    {
        cout 
    << "B call ";
        _c
    ->Function();
    }


    void Mediator::CCallA()
    {
        cout 
    << "C call ";
        _a
    ->Function();
    }


    void Mediator::CCallB()
    {
        cout 
    << "C call ";
        _b
    ->Function();
    }


    void main()
    {
        A a;
        B b;
        C c;

        Mediator m(
    &a, &b, &c);

        a.SetMediator(
    &m);
        b.SetMediator(
    &m);
        c.SetMediator(
    &m);

        a.ACallB();
        a.ACallC();

        b.BCallA();
        b.BCallC();

        c.CCallA();
        c.CCallB();
    }

    我们看到,main() 函数写在 Mediator.CPP 中,里面的调用基本上和上一篇的调用一样,唯一不同的是多了Mediator对象的加入。a、b、c 三个对象也不需要设置两个协助者了,只需要设置一个Mediator就行了,而调用和上篇完全一样(当然在内部实现是不一样的,但在接口的看来,它们是没什么变化的),这样就把三个类之间复杂的关系解开了。

    我们再看看其他三个类的变化,先看看类A,其余两个是差不多的。
    // A.H
    #ifndef _A_H
    #define _A_H

    class B;
    class C;
    class Mediator;

    class A
    {
    public:
        
    void SetMediator(Mediator *m);
        
    void ACallB();
        
    void ACallC();
        
    void Function();
    private:
        B 
    *_b;
        C 
    *_c;
        Mediator 
    *_m;
    }
    ;

    #endif

    // A.CPP
    #include "a.h"
    #include 
    "b.h"
    #include 
    "c.h"
    #include 
    "Mediator.h"

    #include 
    <iostream>
    using namespace std;

    void A::SetMediator(Mediator *m)
    {
        _m 
    = m;
    }


    void A::ACallB()
    {
        _m
    ->ACallB();
    }


    void A::ACallC()
    {
        _m
    ->ACallC();
    }


    void A::Function()
    {
        cout 
    << "A's Func!" << endl;
    }

     可以看看类A中原来调用其他类的服务,现在都变成了调用 Mediator 中的服务了,再看看 Mediator 的实现,就应该会明白这个模式的思想所在了。

    下面再看看其他两个类的实现:
    // B.H

    #ifndef _B_H
    #define _B_H

    class A;
    class C;
    class Mediator;

    class B
    {
    public:
        
    void SetMediator(Mediator *m);
        
    void BCallA();
        
    void BCallC();
        
    void Function();

    private:
        A 
    *_a;
        C 
    *_c;    
        Mediator 
    *_m;
    }
    ;

    #endif


    // B.CPP

    #include "a.h"
    #include 
    "b.h"
    #include 
    "c.h"
    #include 
    "Mediator.h"

    #include 
    <iostream>
    using namespace std;

    void B::SetMediator(Mediator *m)
    {
        _m 
    = m;
    }


    void B::BCallA()
    {
        _m
    ->BCallA();
    }


    void B::BCallC()
    {
        _m
    ->BCallC();
    }


    void B::Function()
    {
        cout 
    << "B's Func!" << endl;
    }

    // C.H

    #ifndef _C_H
    #define _C_H

    class A;
    class B;
    class Mediator;

    class C
    {
    public:
        
    void SetMediator(Mediator *m);
        
    void CCallA();
        
    void CCallB();
        
    void Function();

    private:
        A 
    *_a;
        B 
    *_b;
        Mediator 
    *_m;
    }
    ;

    #endif


    // C.CPP

    #include "a.h"
    #include 
    "b.h"
    #include 
    "c.h"
    #include 
    "Mediator.h"

    #include 
    <iostream>
    using namespace std;


    void C::SetMediator(Mediator *m)
    {
        _m 
    = m;
    }


    void C::CCallA()
    {
        _m
    ->CCallA();
    }


    void C::CCallB()
    {
        _m
    ->CCallB();
    }


    void C::Function()
    {
        cout 
    << "C's Func!" << endl;
    }

    我们可以看到,一二两篇代码的执行结果完全相同,但使用了Mediator模式之后,原来在各个对象内部所做的事情,现在全部移交到Mediator里了。也就是将分布在各个对象里面的协议处理过程,全部统一放在Mediator里去做了。骤看来,好像我们是把职责转移了,但是对于代码逻辑的清晰却有很大的好处,这个模式让我们能专注于各个对象之间的交互(他们的交互都放在Mediator类里去做了)。

    我们还可以看出,Mediator的核心思想就是把错综复杂的类间的关系独立出来,使得他们的关系清晰化。这样做的
    好处是如果类间的交互协议有变化,则只修改Mediator类就行了,但是它的缺点也在于Mediator类,因为所有的
    交互都转移到Mediator中,他的复杂性可想而知,搞不好会变成一个庞然大物,难以维护。

    这里还是希望大家能动手实现一下,由于关系有点乱,没办法做到傻瓜式的简单。我考虑过如果使用两个
    对象来演示又太简单,收不到应有的效果,使用三个对象又会很难描述,所以还是希望大家仿照这两个例子,
    动手实现一下,只要你在机器上编完这两个例子(或者你自己突发奇想的例子),然后再思考一下,一定会对Mediator模式有个清晰的认识!

    发表于 @ 2006年08月14日 19:33:00|评论(loading...)|编辑

    新一篇: UML类图关系全面剖析 | 旧一篇: 设计模式简单代码之Mediator模式(一)

    评论

    #hzq3554055 发表于2008-10-14 17:22:44  IP: 203.171.224.*
    设计模式是解决了些问题 但还是在oo或者说其他什么的框子里打转,跳出这个框子也许会更简单;

    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © 一雨田