您的位置:首页 > 其它

【设计模式学习笔记十八】【行为模式】【中介者模式(Mediator)】

2015-02-08 14:07 615 查看
本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:/article/1610242.html

主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。

我应该理解和掌握的:

1)能够画出这个设计模式的架构框图;

2)能够根据架构框图写出对应的伪代码;

3)这个模式的应用场景,主要优缺点。

1.中介者模式

假如一个系统中对象之间的联系呈现网状结构,也就是对象与对象之间存在大量的多对多关系;几乎每个对象都需要与其他对象发生作用,极端情况下,每个对象都必须直接引用其他对象。通过引入中介者模式,可以将系统的网状结构变成以中介者为中心的星型结构。这样的话,对象之间的作用不再是彼此的直接引用,而是统一通过中介者来进行相互的交互,把复杂的多对多关系转化为相对简单的一对多关系。中介者模式是“迪米特法则”的一个典型应用。

(1)定义

中介者模式:用一个中介对象(中介者)来封装一系列的对象交互;由中介者使各对象不需要显示的相互引用,从而使其解耦,而且可以独立的改变他们之间的交互。又称调停者模式。

1) 中介者模式结构图



2) 参与者

a) Mediator(抽象中介者):定义一个接口用于与各同事对象通信。
b) ConcreteMediator(具体中介者):维持对各个同事对象的引用,协调各同事对象,实现协作行为。
c) Colleague(抽象同事类):定义各个同事共有的方法;维持一个抽象中介者的引用。
d) ConcreteColleague(具体同事类):具体子类,与其他同事通信时,需要通过中介者,来简介完成。
e) 协作:同事向一个中介者对象发送和接受请求。中介者在各同事间适当的转发请求以实现协作行为。

3) 看图写代码

/*
 ** FileName     : MediatorPattern
 ** Author       : lin005
 ** Date         : 2015/02/08
 ** Description  : More information, please go to http://blog.csdn.net/amd123456789  */
#include<iostream>
using namespace std;
class Colleague;
//抽象中介者
class Mediator
{
public:
    //某个同事发生变化
    virtual void colleagueChanged(Colleague* c) = 0;
};
//抽象同事类
class Colleague
{
public:
    Colleague(){}
    virtual void update() = 0;
    //发生变化,调用中介者
    void changed()
    {
        md->colleagueChanged(this);
    }
    //注入中介者
    void setMediator(Mediator* m)
    {
        md = m;
    }
private:
    //每个同事类都包含一个中介者引用
    Mediator* md;
};
//具体同事对象A
class ColleagueA : public Colleague
{
public:
    ColleagueA(){}
    //更新
    virtual void update()
    {
        cout<<"ColleagueB is changed!"<<endl;
        cout<<"ColleagueA need update!"<<endl;
    }
};
//具体同事对象B
class ColleagueB : public Colleague
{
public:
    ColleagueB(){}
    virtual void update()
    {
        cout<<"ColleagueA is changed!"<<endl;
        cout<<"ColleagueB need update!"<<endl;
    }
};
//具体中介者对象
class ConcreteMediator : public Mediator
{
public:
    ConcreteMediator(Colleague* a, Colleague* b):A(a),B(b){}
    //中介者对象主要处理逻辑
    virtual void colleagueChanged(Colleague* c)
    {
        if(c == A)//A对象发生变化
        {
            B->update();
        }
        else if(c == B)//B对象发生变化
        {
            A->update();
        }
        else
        {
            cout<<"no colleague need update!"<<endl;
        }
    }
private:
    //中介者类必须持有所有同事对象
    Colleague* A;
    Colleague* B;
};
//客户端测试
#define SAFE_DELETE(p) if(p){delete p; p = NULL;}
int main(int argc, const char * argv[]) {
    //具体同事对象ab
    Colleague* a = new ColleagueA();
    Colleague* b = new ColleagueB();
    //中介者对象
    Mediator* md = new ConcreteMediator(a, b);
    //为同事对象注入中介者
    a->setMediator(md);
    b->setMediator(md);
    //ab改变
    a->changed();
    b->changed();
    return 0;
}


(2)总结

1) 优点

a) 减少子类的生成;将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成Mediator的子类即可,这样各个Colleague可以重用。
b) 将各Colleague解耦;有利于各Colleague间的松耦合,可以独立的改变和复用各Colleague类和Mediator类。增加新的同事和中介者都很方便,符合开闭。
c) 简化了对象协议;用Mediator和各Colleague间的一对多关系代替多对多的交互。一对多易于理解,维护,和扩展。

2) 缺点

a) 控制集中化,中介者模式将交互的复杂性变为中介者的复杂性。因为中介者封装了协议,他可能变得比任何一个colleague都复杂。可能是中介者自身成为一个难于维护的庞然大物。

(3)适用场景

1)一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱而且难以理解。

2)一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。

3)想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以引入中介者,在中介者中定义对象交互的公共行为,如要需要改变行为则可以增加新的具体中介者类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: