中介者,说白了跟市面上黑中介类似。当然这个中介,开发者是可以控制其行为的。也是在一定的信任关系上建立的。
该模式要解决的问题是,一堆对象之间交叉耦合问题。
网上看过群聊的例子。如果没有任何一个平台,多人之间的会话会是什么样的呢?不举多人,就三个吧A想把一句话说给BC,那么他首先要知道B和C在哪儿,然后分别告诉对方,自己想说的事情。如果再加一个人呢?
问题很明显,此时各种群聊工具应运而生。我写了个简单的demo:
/*************************************************************************** * * Copyright (c) 2013 itegel.com, Inc. All Rights Reserved * **************************************************************************/ /** * @file test_mediator.cpp * @author itegel * @date 2013/06/05 17:00:07 * @brief 群聊的例子 * **/ #include <string> #include <vector> #include <iostream> #include <time.h> #include <sstream> using namespace std; class Mediator; //抽象colleague class Colleague{ public: Colleague(string & name, Mediator * media):_name(name){ _mediator = media; } void SetName(string & name){ _name = name; } string GetName(){ return _name; } void SetContent(string content){ _content = content; } string GetContent(){ return _content; } virtual void talk(){ cout<<this->GetName()<<" saied:"<<this->GetContent()<<endl; } Mediator * GetMediator(){ return _mediator; } protected: string _name; string _content; Mediator * _mediator; }; class Mediator{ public: Mediator(){ _history = ""; } void AddColleague(Colleague * clg){ _colleagues.push_back(clg); } virtual void Notify(){ for(vector<Colleague *>::iterator iter = _colleagues.begin(); iter != _colleagues.end(); iter++){ (*iter)->talk(); } } void AppendHistory(string new_content){ time_t t = time(NULL); struct tm* ct = localtime(&t); ostringstream oss; oss<<ct->tm_mon + 1<<"-"<<ct->tm_mday<<" "<<ct->tm_hour<<":"<<ct->tm_min<<":"<<ct->tm_sec<<" "; oss<<new_content<<"\n"; _history += oss.str(); } string GetHistory(){ return _history; } protected: vector<Colleague *> _colleagues; string _history; }; class ColleagueA : public Colleague{ public: ColleagueA(string name, Mediator * media):Colleague(name, media){ } ~ColleagueA(){} virtual void talk(){ cout<<this->GetName()<<" saied:"<<this->GetContent()<<endl; _mediator->AppendHistory(this->GetName()+":"+this->GetContent()); } }; class ColleagueB : public Colleague{ public: ColleagueB(string name, Mediator * media):Colleague(name, media){ } ~ColleagueB(){} virtual void talk(){ cout<<this->GetName()<<" saied:"<<this->GetContent()<<endl; _mediator->AppendHistory(this->GetName()+":"+this->GetContent()); } }; class Hi : public Mediator{ public: Hi(){} ~Hi(){} }; int main(){ Hi hi; ColleagueA * A1 = new ColleagueA("A1", &hi); ColleagueB * B1 = new ColleagueB("B1", &hi); ColleagueB * B2 = new ColleagueB("B2", &hi); hi.AddColleague(A1); hi.AddColleague(B1); hi.AddColleague(B2); A1->SetContent("I am hungry!"); B1->SetContent("I am hungry too!"); B2->SetContent("Let's go out and have sth. to eat!"); hi.Notify(); sleep(1); A1->SetContent("田老师?"); B1->SetContent("米线吧?"); B2->SetContent("有会,还是食堂吧!"); hi.Notify(); sleep(1); cout<<endl<<A1->GetName()<<" 查看聊天记录:"<<endl; cout<<A1->GetMediator()->GetHistory()<<endl;; return 0; }
执行结果:
A1 saied:I am hungry! B1 saied:I am hungry too! B2 saied:Let's go out and have sth. to eat! A1 saied:田老师? B1 saied:米线吧? B2 saied:有会,还是食堂吧! A1 查看聊天记录: 6-5 19:34:59 A1:I am hungry! 6-5 19:34:59 B1:I am hungry too! 6-5 19:34:59 B2:Let's go out and have sth. to eat! 6-5 19:35:0 A1:田老师? 6-5 19:35:0 B1:米线吧? 6-5 19:35:0 B2:有会,还是食堂吧!
中介者实际实现可以有很多种,要看具体应用。
用中介者的坏处估计也是跟黑中介类似,比如租房,实际上我只需要跟房东打交道就好。但是因为中介的介入,我同样的接口(比如电话号码)可能还得暴露给中介者!