您的位置:首页 > 其它

设计模式笔记-Mediator

2016-06-02 16:32 393 查看
中介者模式:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。这个定义说白了,两个对象要交互(或者说通信,随便怎么说吧),直接组合对方的类指针的话耦合性太高。中间用一个类包装一下,这样,相互通信的类里面直接通过这个包装类操作就行了!说实在的,我没有实际用过这个模式,也没体会过它的好处,我就通过总结网上别人的帖子来写一下。



几点说明:

1. Mediator为什么还要派生一个子类?意思是这里的两同事交流用ConcreteMediator,如果另外有两个类老师和同学,那也可以通过Mediator派生出另一个类来交流吗? 

2. 两个交流的类,必须是继承同一个类的兄弟吗?为什么?

这些问题在脑子里都是要推敲的,不然不知道应用场景的话,光死记一个模式的用处和实现,没意义,真正在项目中需要的时候,你还是想不到用它!有知道的麻烦给我留言,谢谢!

通过上面的UML图,可以知道:

1. mediator类里面肯定要组合两个colleague类的指针,不然怎么连接它们两呢?

2. colleague中也必须要组合一个mediator指针,不然它的两个派生类没法通过mediator来操作。这里面实现的时候,colleague和mediator,你只能在其中一个构造函数中传入对方的指针,另一个要在定义之后,用setXXX函数传入。见下面的代码!

3. Mediator中要保存交互双方的指针,怎么个保存逻辑我没见过好的实现,只保存两个?只能满足固定两方的通信吗?如果有很多对儿对象通信呢?如果他们还是不同类型(不是派生于同一个基类)的呢?下面的实现就是保存2个指针,sendMsg()里判断:不是这个就是另一个,弱爆了,但我也没见有好的实现。看这一篇,PHP实现的,我觉得他的设计模式的博文写的都还不错。其它好多人的,真是误人子弟!

下面代码是我综合别人的实现写出来的,把该模式的思想还是表达出来了的。操作接口也尽量简洁!

#include<string>
#include "student.h"

class Student;
class Mediator {
public:
void setCommunicators(Student* a, Student* b);
void sendMsg(Student*, std::string);
private:
Student* _com1;
Student* _com2;
};
#include "mediator"
void Mediator::setCommunicators(Student* a, Student* b)
{
_com1 = a;
_com2 = b;
}

void Mediator::sendMsg(Student* a, string s)
{
if (a == _com1)
_com2->recv(s);
else
_com1->recv(s);
}
#include"mediator.h"
#include<string>
using std::string;

class Mediator;
class Student {

public:
virtual void send(string)=0;
virtual void recv(string)=0;
protected:
Mediator* _mediator;
string _msg;
};

class StudentA :public Student{
public:
StudentA(Mediator*);
virtual void send(string);
virtual void recv(string);
};

class StudentB :public Student {
public:
StudentB(Mediator*);
virtual void send(string);
virtual void recv(string);
};
#include "student.h"
StudentA::StudentA(Mediator* m) {
_mediator = m;
}
void StudentA::send(string s)
{
_mediator->sendMsg(this, s);
}
void StudentA::recv(string s)
{
_msg = s;
cout << "Student B: " << s << endl; //A收到B的信息
}
StudentB::StudentB(Mediator* m) {
_mediator = m;
}
void StudentB::send(string s)
{
_mediator->sendMsg(this, s);
}
void StudentB::recv(string s)
{
_msg = s;
cout << "Student A: " << s << endl; //B收到A的信息</span>
}
客户端代码:

int main()
{
Mediator* med = new Mediator;
Student * a = new StudentA(med);
Student * b = new StudentB(med);
med->setCommunicators(a, b);
a->send("Hello B, how are you!");
b->send("I'm fine!How do you do, A?");
return 0;
}
没事自己实现一下,光看别人写的,就错过了一些实现上的难点,印象也不会深刻!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: