//中介者(Mediator)----对象行为型模式( 学习笔记)
1.意图
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
2.动机
面向对象设计鼓励将行为分布到各个对象中。这种分布会导致对象间有许多连接,可以通过将这些有联系的对象行为封装在一个单独的中介者对象中。中介者负责控制和协调一组对象间的交互。中介者充当一个中介以使组中的对象不再相互以显式引用。只鹅写对象仅知道中介者,从而就减少了相互连接的数目。
3.适用性
1)一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
2)一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
3)想定制一个分布在多个类中的行为,而又不想生成太多的子类。
4.结构

5.参与者
*中介者(Mediator)
---定义一个接口用于与各同事对象通信。
*具体中介者(ConcreteMediaor)
---通过协调各同事对象实现协作行为。
---了解并维护它的各个同事。
*同事类(Colleague class)
---每一个同事类都知道他的中介者对象。
---每一个同事对象在需与其他同事通信时,与他的中介者通信。
6.协作
同事向一个中介者对象发送和接收请求。中介者在各同事间适当地转发请求以实现协作行为。
7.实现与例子
/******************************************************
*
* 一个图形用户界面中的对话框的实现,对话框有一系列窗口
* 组件,如按钮,菜单和输入域等。各组件间存在依赖关系。
* FontDialog为对话框中各窗口组件的中介者。它充当窗组件间通
讯的转发中心,如下图1示:

*下面是FontDialogDirector抽象被集成到一个类库中。
如图2示:

*
*
*
*
*************************************/
#include "List.H"
class MouseEvent;
class Widget;
class DialogDirector {
public:
virtual ~DialogDirector();
virtual void ShowDialog();
virtual void WidgetChanged(Widget*) = 0;
protected:
DialogDirector();
virtual void CreateWidgets() = 0;
};
class Widget {
public:
Widget(DialogDirector*);
virtual void Changed();
virtual void HandleMouse(MouseEvent& event);
// ...
private:
DialogDirector* _director;
};
void Widget::Changed () {
_director->WidgetChanged(this);
}
class ListBox : public Widget {
public:
ListBox(DialogDirector*);
virtual const char* GetSelection();
virtual void SetList(List<char*>* listItems);
virtual void HandleMouse(MouseEvent& event);
// ...
};
class EntryField : public Widget {
public:
EntryField(DialogDirector*);
virtual void SetText(const char* text);
virtual const char* GetText();
virtual void HandleMouse(MouseEvent& event);
// ...
};
class Button : public Widget {
public:
Button(DialogDirector*);
virtual void SetText(const char* text);
virtual void HandleMouse(MouseEvent& event);
// ...
};
void Button::HandleMouse (MouseEvent& event) {
// ...
Changed();
}
class FontDialogDirector : public DialogDirector {
public:
FontDialogDirector();
virtual ~FontDialogDirector();
virtual void WidgetChanged(Widget*);
protected:
virtual void CreateWidgets();
private:
Button* _ok;
Button* _cancel;
ListBox* _fontList;
EntryField* _fontName;
};
void FontDialogDirector::CreateWidgets () {
_ok = new Button(this);
_cancel = new Button(this);
_fontList = new ListBox(this);
_fontName = new EntryField(this);
// fill the listBox with the available font names
// assemble the widgets in the dialog
}
void FontDialogDirector::WidgetChanged (
Widget* theChangedWidget
) {
if (theChangedWidget == _fontList) {
_fontName->SetText(_fontList->GetSelection());
} else if (theChangedWidget == _ok) {
// apply font change and dismiss dialog
// ...
} else if (theChangedWidget == _cancel) {
// dismiss dialog
}
}