设计模式笔记-Mediator

来源:互联网 发布:中国与英国知乎 编辑:程序博客网 时间:2024/05/22 11:30

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


几点说明:

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;}
没事自己实现一下,光看别人写的,就错过了一些实现上的难点,印象也不会深刻!

0 0
原创粉丝点击