定义


用一个中介对象来封装一系列的对象的交互。中介者使各对象不须要显示地相互使用,从而使其耦合松散,并且能够独立的改变他们之间的交互。
案例
比方有一个图像界面,在界面上有一个输入框LineEdit,有个一个列表框ListBox,有一个buttonButton。当输入框LineEdit没有内容的时候,button是灰显,不可用的,当在LineEdit输入了正确的选项后,ListBox也会跳转到改选项,Button被激活,能够操作。相同ListBox也能够选择不同的选项,改变LineEdit的内容,当Button能够使用的时候能够删除被选中的选项,这样各个窗体间有比較强的依赖关系,能够通过将集体行为封装在一个单独的中介者Mediator对象中来避免这个问题:

Mediator定义了中介类的一个接口:
class Mediator {public:virtual void showDialog() = 0;virtual void widgetChanged(Widget*) = 0;protected:Mediator();virtual void createWidgets() = 0;};
Widget是全部窗体类的基类:
class Widget {public:Widget(Mediator* mediator) { m_mediator = mediator; }virtual void changed(){ }Mediator* mediator() const { return m_mediator; }private:Mediator* m_mediator;};
LineEdit类是一个文字输入窗体类:
class LineEdit : public Widget {public:LineEdit(Mediator*);virtual void changed();void setText(const string& text);string text() const;private:string m_text;};void LineEdit::changed(){mediator()->widgetChanged(this);}
Button和ListBox都是继承自Widget的类,并实现了自己独有的操作。
如今创建一个DialogMediator类把全部的窗体类联系起来:
class DialogMediator : public Mediator {public:virtual void widgetChanged(Widget* widget);virtual void showDialog();protected:virtual void createWidgets();private:LineEdit* m_lineEdit;ListBox* m_listBox;Button* m_button;};void DialogMediator::createWidgets(){m_lineEdit = new LineEdit();...}void DialogMediator::widgetChanged(Widget* widget){if(widget == m_lineEdit){m_listBox->setSelection(m_lineEdit->text());m_button->setEnable(true);}else if(m_listBox){m_lineEdit->setText(m_listBox->getSeletion());m_button->setEnable(true);}else{m_lineEdit->setText("");m_listBox->setSelection(lastOne);}}
DialogMediator mediator;mediator.createWidgets();mediator.showDialog();
适用性
- 一组对象以定义良好可是通过复杂的方式进行通信,产生的依赖结构混乱
- 一个对象引用其它非常多对象而且直接与这些对象进行通信,导致难以复用该对象
- 想定制一个分布在多个类中的行为,而不想生成太多的子类
优缺点
- 降低了子类的生成
- 将各个类进行了解耦
- 简化了对象协议,一对多的关系易于理解
- 对对象怎样协作进行了抽象
- 使控制集中化,使得中介者类自身庞大,难于维护