Mediator

Structural example

#include <iostream>
#include <string>
using namespace std;
 
 
class Colleague;
class ConcreteColleague1;
class ConcreteColleague2;
 
// 仲介者
class Mediator {
public:
	virtual void Send(const string &message, Colleague *colleague) = 0;
};
 
class ConcreteMediator : public Mediator {
private:
	ConcreteColleague1 *_colleague1;
	ConcreteColleague2 *_colleague2;
public:
	void SetColleague1(ConcreteColleague1 *value) {
		_colleague1 = value;
	}
	void SetColleague2(ConcreteColleague2 *value) {
		_colleague2 = value;
	}
	virtual void Send(const string &message, Colleague *colleague);
};
 
 
// 同業者
class Colleague {
protected:
	Mediator *mediator;
public:
	Colleague(Mediator *mediator) {
		this->mediator = mediator;
	}
};
 
class ConcreteColleague1 : public Colleague {
public:
	ConcreteColleague1(Mediator *mediator)
		: Colleague(mediator) { }
	void Send(const string &message) {
		mediator->Send(message, this);
	}
	void Notify(const string &message) {
		cout << "Colleague1 gets message: " << message << endl;
	}
};
 
class ConcreteColleague2 : public Colleague {
public:
	ConcreteColleague2(Mediator *mediator)
		: Colleague(mediator) { }
	void Send(const string &message) {
		mediator->Send(message, this);
	}
	void Notify(const string &message) {
		cout << "Colleague2 gets message: " << message << endl;
	}
};
 
 
///////
void ConcreteMediator::Send(const string &message, Colleague *colleague) {
	if (colleague == _colleague1) {
		_colleague2->Notify(message);
	} else {
		_colleague1->Notify(message);
	}
}
 
 
///////
int main() {
	ConcreteMediator *m = new ConcreteMediator();
 
	ConcreteColleague1 *c1 = new ConcreteColleague1(m);
	ConcreteColleague2 *c2 = new ConcreteColleague2(m);
 
	m->SetColleague1(c1);
	m->SetColleague2(c2);
 
	c1->Send("How are you?");
	c2->Send("Fine, thanks");
 
	delete c1;
	delete c2;
	delete m;
	return 0;
}
 


Real World example

#include <iostream>
#include <string>
#include <map>
using namespace std;
 
class Participant;
 
// Mediator class
class AbstractChatroom {
public:
	virtual void Register(Participant *participant) = 0;
	virtual void Send(const string &from, const string &to, const string &message) = 0;
};
 
// ConcreteMediator class
class Chatroom : public AbstractChatroom {
private:
	map<string, Participant*> _participants;
public:
	virtual void Register(Participant *participant);
	virtual void Send(const string &from, const string &to, const string &message);
};
 
 
// Colleague class
class Participant {
private:
	Chatroom *_chatroom;
	string _name;
public:
	Participant(const string &name) {
		_name = name;
	}
	string getName() {
		return _name;
	}
	void setChatroom(Chatroom *chatroom) {
		_chatroom = chatroom;
	}
	Chatroom* getChatroom() {
		return _chatroom;
	}
	void Send(const string &to, const string &message) {
		_chatroom->Send(_name, to, message);
	}
	virtual void Receive(const string &from, const string &message) {
		cout << from << " to " << _name << ": \'" << message << "\'" << endl;
	}
};
 
// ConcreteColleague class
class Beatle : public Participant {
public:
	Beatle(const string &name) : Participant(name) { }
	virtual void Receive(const string &from, const string &message) {
		cout << "To a Beatle: ";
		Participant::Receive(from, message);
	}
};
 
class NonBeatle : public Participant {
public:
	NonBeatle(const string &name) : Participant(name) { }
	virtual void Receive(const string &from, const string &message) {
		cout << "To a non-Beatle: ";
		Participant::Receive(from, message);
	}
};
 
 
/////
void Chatroom::Register(Participant *participant) {
	Participant *p = _participants[participant->getName()];
	if (p == NULL) {
		// register
		participant->setChatroom(this);
		_participants[participant->getName()] = participant;
	}
}
 
void Chatroom::Send(const string &from, const string &to, const string &message) {
	Participant *participant = _participants[to];
	if (participant != NULL) {
		participant->Receive(from, message);
	}
}
 
 
///////
int main() {
	// create chatroom
	Chatroom *chatroom = new Chatroom;
 
	// create participants and register them
	Participant *George = new Beatle("George");
	Participant *Paul = new Beatle("Paul");
	Participant *Ringo = new Beatle("Ringo");
	Participant *John = new Beatle("John");
	Participant *Yoko = new NonBeatle("Yoko");
 
	chatroom->Register(George);
	chatroom->Register(Paul);
	chatroom->Register(Ringo);
	chatroom->Register(John);
	chatroom->Register(Yoko);
 
	// Chatting participants
	Yoko->Send("John", "Hi John!");
	Paul->Send("Ringo", "All you need is Love");
	Ringo->Send("George", "My sweet Lord");
	Paul->Send("John", "Can't buy me love");
	John->Send("Yoko", "My sweet love");
 
	delete George;
	delete Paul;
	delete Ringo;
	delete John;
	delete Yoke;
	delete chatroom;
	return 0;
}
 


参考サイト

デザインパターンを“喩え話”で分かり易く理解する
http://www.netlaputa.ne.jp/~hijk/study/oo/designpattern.html



デザインパターンの骸骨たち
http://www002.upp.so-net.ne.jp/ys_oota/mdp/

デザインパターンの使い方: Mediator
http://japan.internet.com/developer/20090106/26.html
最終更新:2011年12月08日 01:37