首页 > 代码库 > Mediator - 中介者模式

Mediator - 中介者模式

定义
用一个中介对象来封装一系列的对象的交互。中介者使各对象不需要显示地相互使用,从而使其耦合松散,而且可以独立的改变他们之间的交互。

案例
比如有一个图像界面,在界面上有一个输入框LineEdit,有个一个列表框ListBox,有一个按钮Button。当输入框LineEdit没有内容的时候,按钮是灰显,不可用的,当在LineEdit输入了正确的选项后,ListBox也会跳转到改选项,Button被激活,可以操作。同样ListBox也可以选择不同的选项,改变LineEdit的内容,当Button可以使用的时候可以删除被选中的选项,这样各个窗口间有比较强的依赖关系,可以通过将集体行为封装在一个单独的中介者Mediator对象中来避免这个问题:


Mediator定义了中介类的一个接口:
  1. class Mediator {
  2. public:
  3. virtual void showDialog() = 0;
  4. virtual void widgetChanged(Widget*) = 0;
  5. protected:
  6. Mediator();
  7. virtual void createWidgets() = 0;
  8. };
Widget是所有窗口类的基类:
  1. class Widget {
  2. public:
  3. Widget(Mediator* mediator) { m_mediator = mediator; }
  4. virtual void changed(){ }
  5. Mediator* mediator() const { return m_mediator; }
  6. private:
  7. Mediator* m_mediator;
  8. };

LineEdit类是一个文字输入窗口类:
  1. class LineEdit : public Widget {
  2. public:
  3. LineEdit(Mediator*);
  4. virtual void changed();
  5. void setText(const string& text);
  6. string text() const;
  7. private:
  8. string m_text;
  9. };
  10. void LineEdit::changed()
  11. {
  12. mediator()->widgetChanged(this);
  13. }
Button和ListBox都是继承自Widget的类,并实现了自己独有的操作。
现在创建一个DialogMediator类把所有的窗口类联系起来:
  1. class DialogMediator : public Mediator {
  2. public:
  3. virtual void widgetChanged(Widget* widget);
  4. virtual void showDialog();
  5. protected:
  6. virtual void createWidgets();
  7. private:
  8. LineEdit* m_lineEdit;
  9. ListBox* m_listBox;
  10. Button* m_button;
  11. };
  12. void DialogMediator::createWidgets()
  13. {
  14. m_lineEdit = new LineEdit();
  15. ...
  16. }
  17. void DialogMediator::widgetChanged(Widget* widget)
  18. {
  19. if(widget == m_lineEdit)
  20. {
  21. m_listBox->setSelection(m_lineEdit->text());
  22. m_button->setEnable(true);
  23. }
  24. else if(m_listBox)
  25. {
  26. m_lineEdit->setText(m_listBox->getSeletion());
  27. m_button->setEnable(true);
  28. }
  29. else
  30. {
  31. m_lineEdit->setText("");
  32. m_listBox->setSelection(lastOne);
  33. }
  34. }
  1. DialogMediator mediator;
  2. mediator.createWidgets();
  3. mediator.showDialog();
适用性
  • 一组对象以定义良好但是通过复杂的方式进行通信,产生的依赖结构混乱
  • 一个对象引用其他很多对象并且直接与这些对象进行通信,导致难以复用该对象
  • 想定制一个分布在多个类中的行为,而不想生成太多的子类
优缺点
  1. 减少了子类的生成
  2. 将各个类进行了解耦
  3. 简化了对象协议,一对多的关系易于理解
  4. 对对象如何协作进行了抽象
  5. 使控制集中化,使得中介者类自身庞大,难于维护