设计模式笔记-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实现的,我觉得他的设计模式的博文写的都还不错。其它好多人的,真是误人子弟!
下面代码是我综合别人的实现写出来的,把该模式的思想还是表达出来了的。操作接口也尽量简洁!
几点说明:
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; }没事自己实现一下,光看别人写的,就错过了一些实现上的难点,印象也不会深刻!
相关文章推荐
- 关于drawable和mipmap
- ES6在线学习
- 数组分组
- Sqrt(x)
- STORM_0008_Structure-of-the-codebase_Storm的代码库的结构
- jquery 圆形进度条
- 日文学习v1.0(本人有点精分,文中各种吐槽风慎入)
- KMP算法简易图解
- avformat_open_input()源码分析
- Spring 3 MVC深入研究
- 希尔排序
- 数列 [Bzoj3142,Codevs2089,HNOI2013]
- 【android】:android实现监听多个按钮事件
- 我的 VC++ 常见错误问题解决办法
- JavaScript:闭包
- PHP 5.5 新特性关键字 yield
- Python变量与常量
- shell 实例收集
- Picasso入门教程(三)
- CodeForces 24B-F1 Champions