意图:
用一个中介对象来封装一系列对象交互.中介者使各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立改变他们之间的交互
适用性:
1一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解
2一组对象引用其它很多对象并且直接与这些对象通信,导致难以复用该对象
3想定制一个分布在多个类中的行为,而又不想生成太多的子类
效果:
1减少了子类生成。Mediator将原来分布于多个对象间的行为集中在一起。改变这些行为只需要生成Mediator的子类即可
2它将各Colleague解耦。有利于各Colleague间的松耦合。可以独立的改变和复用各Colleague类和Mediator类
3简化了对象协议。用Mediator和各Colleague间的一对多的交互来代替多对多的交互
4对对象如何协作进行了抽象 将中介作为一个独立的概念并将其封装在一个对象中,有助于弄清一个系统中的对象是如何交互的。
5控制集中化 中介者模式将交互的复杂性变为中介者的复杂性
实现:
1忽略抽象的Mediator类 当各Colleague仅与一个Mediator工作时,没有必要定义一个抽象的Mediator类
2 Colleague-Mediator通信 有两种方式
a Observer模式,将Mediator实现为一个Observer,各Colleague作为Subject,一旦其状态改变就发送通知给Mediator
b 在Mediator中定义一个特殊的通知接口,各Colleague通信时直接调用该接口
The code is as below:
Mediator.h
- #include <iostream>
- using namespace std;
- class Widget;
- class DialogDirector
- {
- public:
- virtual ~DialogDirector() {cout<<"Destory DialogDirector"<<endl;}
- //virtual void ShowDialog();
- virtual void WidgetChanged(Widget*) = 0;
- protected:
- DialogDirector() {cout<<"Create DialogDirector"<<endl;}
- virtual void CreateWidgets() {cout<<"Create Widgets"<<endl;}
- };
- class Widget
- {
- public:
- Widget(DialogDirector* s)
- {
- _director=s;
- cout<<"Create Widget"<<endl;
- }
- virtual void Changed()
- {
- _director->WidgetChanged(this);
- }
- // virtual void HandleMouse(MouseEvent& event);
- private:
- DialogDirector* _director;
- };
- class ListBox : public Widget
- {
- public:
- ListBox(DialogDirector* s): Widget(s) {cout<<"Create ListBox."<<endl;}
- //virtual const char* GetSelection();
- //virtual void SetList
- virtual void HandleMouse()
- {
- Changed();
- }
- };
- class EntryField : public Widget
- {
- public:
- EntryField(DialogDirector* s): Widget(s) {cout<<"Create EntryField."<<endl;}
- //virtual void SetText(const char* text);
- // virtual const char* GetText();
- virtual void HandleMouse()
- {
- Changed();
- }
- };
- class Button: public Widget
- {
- public:
- Button(DialogDirector* s): Widget(s) {cout<<"Create Button."<<endl;}
- //virtual void SetText(const char* text);
- virtual void HandleMouse()
- {
- Changed();
- }
- };
- class FontDialogDirector : public DialogDirector
- {
- public:
- FontDialogDirector() {cout<<"Create FontDialogDirector."<<endl;}
- virtual ~FontDialogDirector() {cout<<"Destory FontDialogDirector."<<endl;}
- virtual void WidgetChanged(Widget*);
- virtual void CreateWidgets(Button* s ,Button* t,ListBox* r, EntryField* w);
- Button* _ok;
- Button* _cancel;
- ListBox* _fontlist;
- EntryField* _fontName;
- };
Mediator.cpp
- #include <iostream>
- using namespace std;
- #include "Mediator.h"
- void FontDialogDirector::CreateWidgets(Button* s ,Button* t,ListBox* r,EntryField* w)
- {
- _ok = new Button(this);
- _cancel = new Button(this);
- _fontlist = new ListBox(this);
- _fontName = new EntryField(this);
- s = _ok;
- t = _cancel;
- r = _fontlist;
- w = _fontName;
- }
- void FontDialogDirector::WidgetChanged(Widget* theChangedWidget)
- {
- if (theChangedWidget == _fontlist)
- {
- cout<<"The font is changed in font list ."<<endl;
- }
- if (theChangedWidget == _ok)
- {
- cout<<"Change the Font and dismiss the dialog."<<endl;
- }
- if (theChangedWidget == _cancel)
- {
- cout<<"Dismiss the dialog."<<endl;
- }
- }
main.cpp
- #include "Mediator.h"
- #include <iostream>
- using namespace std;
- int main()
- {
- FontDialogDirector a;
- Button* ok;
- Button* cancel;
- ListBox* fontlist;
- EntryField* fontName;
- a.CreateWidgets(ok,cancel,fontlist,fontName);
- (a._ok)->HandleMouse();
- return 0;
- }