どんなもの?
- 複雑に絡みあった複数のオブジェクト間の関係を、必ず仲介者を介して処理を行うようにすることで、単純かつ明快なインターフェースを提供する。
- 管轄下にある複数のオブジェクトから問い合わせをうけ、判断を行い、管轄下のオブジェクトへ指示を出す
どういうときに使う?
- 複数のオブジェクトが相互に同期して機能するとき
例
典型的な構成要素
- Mediator
- Colleagueからの相談を受け、それを元に判断を下し、Colleagueへ指示をだす。
- 各Colleagueからの相談受付の窓口インターフェースを定義する。
- 管轄下に置くColleagueを格納するためのインターフェースを定義する
- ConcreteMediator
- Mediatorのインターフェースを実装する。実際にColleaguを保持し、そこから相談を受け、判断を下し、それらに指示を出す。
- Colleague
- 他のColleaguを制御したい場合は、Mediatorに相談する。
- Mediatorからの指示を受ける窓口インターフェースを定義する。
- 自身が相談するMediatorを格納保持するための関数を定義する。
- ConcreteColleague
- Client
コード
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Mediator{
public:
virtual void createColleague(void) = 0;
virtual void colleagueModeChange(const string &name) = 0;
private:
};
class Colleague{
public:
Colleague(Mediator *mediator):mediator(mediator){};
virtual void modeChange(void) = 0;
virtual void receiveModeChange(const string &name) = 0;
protected:
Mediator *mediator;
};
class ConcreteColleagueA: public Colleague{
public:
ConcreteColleagueA(Mediator *mediator):Colleague(mediator){};
void modeChange(void){
cout << "ConcreteColleagueA changes mode" << endl;
mediator->colleagueModeChange("a");
}
void receiveModeChange(const string &name){
cout << "ConcreteColleagueA receives mode change from " << name << endl;
}
private:
};
class ConcreteColleagueB: public Colleague{
public:
ConcreteColleagueB(Mediator *mediator):Colleague(mediator){};
void modeChange(void){
cout << "ConcreteColleagueB changes mode" << endl;
mediator->colleagueModeChange("b");
}
void receiveModeChange(const string &name){
cout << "ConcreteColleagueB receives mode change from " << name << endl;
}
private:
};
class ConcreteColleagueC: public Colleague{
public:
ConcreteColleagueC(Mediator *mediator):Colleague(mediator){};
void modeChange(void){
cout << "ConcreteColleagueC changes mode" << endl;
mediator->colleagueModeChange("c");
}
void receiveModeChange(const string &name){
cout << "ConcreteColleagueC receives mode change from " << name << endl;
}
private:
};
class ConcreteMediator: public Mediator{
public:
void createColleague(void){
ConcreteColleagueA *a = new ConcreteColleagueA(this);
colleague["a"] = a;
ConcreteColleagueB *b = new ConcreteColleagueB(this);
colleague["b"] = b;
ConcreteColleagueC *c = new ConcreteColleagueC(this);
colleague["c"] = c;
}
void colleagueModeChange(const string &name){
for(auto it=colleague.begin();it!=colleague.end();++it){
if(it->first!=name){
it->second->receiveModeChange(name);
}
}
}
void changeMode(const string &name){
for(auto it=colleague.begin();it!=colleague.end();++it){
if(it->first==name){
it->second->modeChange();
}
}
}
private:
map<string, Colleague*> colleague;
};
int main(){
ConcreteMediator *mediator = new ConcreteMediator;
mediator->createColleague();
mediator->changeMode("a");
mediator->changeMode("c");
return 0;
}