中介者,说白了跟市面上黑中介类似。当然这个中介,开发者是可以控制其行为的。也是在一定的信任关系上建立的。
该模式要解决的问题是,一堆对象之间交叉耦合问题。
网上看过群聊的例子。如果没有任何一个平台,多人之间的会话会是什么样的呢?不举多人,就三个吧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:有会,还是食堂吧!
中介者实际实现可以有很多种,要看具体应用。
用中介者的坏处估计也是跟黑中介类似,比如租房,实际上我只需要跟房东打交道就好。但是因为中介的介入,我同样的接口(比如电话号码)可能还得暴露给中介者!