設(shè)計模式之二十一:中介者模式(Mediator)
中介者模式:定義了一個對象。用來封裝一系列對象的交互。中介者模式通過使對象之間不必顯式引用減少了對象之間的耦合,而且同意你獨立改變它們之間的交互。
中介者模式就是將對象之間的交互封裝在了一個獨立的對象中。這個獨立的對象用來控制對象之間的交互行為,所以這個對象還是蠻復(fù)雜的。
UML類圖:
主要包含:
- Mediator:定義了一個Colleague對象之間交互的接口。
- ConcreteMediator:實現(xiàn)了Colleague對象之間的交互行為,并了解和能操作Colleague對象。
- Colleague classes:每個Colleague都認(rèn)識Mediator對象。而且通過Mediator來實現(xiàn)彼此之間的通訊。
基礎(chǔ)C++代碼例如以下:
#include <iostream>
#include <string>
using namespace std;
class Colleague;
class Mediator
{
public:
virtual void send(string message,Colleague * c)=0;
};
class Colleague
{
public:
Colleague(Mediator *m)
{
mediator=m;
}
void send(string message)
{
mediator->send(message,this);
}
virtual void notify(string message)=0;
protected:
Mediator * mediator;
};
class ConcreteColleague1:public Colleague
{
public:
ConcreteColleague1(Mediator * c):Colleague(c)
{
}
void notify(string message)
{
cout<<"concreteColleague1 receive message:"<<message<<endl;
}
};
class ConcreteColleague2:public Colleague
{
public:
ConcreteColleague2(Mediator *m):Colleague(m)
{
}
void notify(string message)
{
cout<<"concreteColleague2 receive message:"<<message<<endl;
}
};
class ConcreteMediator:public Mediator
{
public:
void send(string message,Colleague * c)
{
ConcreteColleague1* c1=dynamic_cast<ConcreteColleague1 *>(c);
ConcreteColleague2* c2=dynamic_cast<ConcreteColleague2 *>(c);
if(c1!=NULL)
{
cc2->notify(message);
}
if(c2!=NULL)
{
cc1->notify(message);
}
}
void setCC1(ConcreteColleague1 * c)
{
cc1=c;
}
void setCC2(ConcreteColleague2 * c)
{
cc2=c;
}
private:
ConcreteColleague1 * cc1;
ConcreteColleague2 * cc2;
};
int main()
{
ConcreteMediator *m=new ConcreteMediator();
ConcreteColleague1 * cc1=new ConcreteColleague1(m);
ConcreteColleague2 * cc2=new ConcreteColleague2(m);
m->setCC1(cc1);
m->setCC2(cc2);
cc1->send("how are you !");
cc2->send("fine ,thank you");
return 0;
}
運行輸出:
一個使用中介者模式的聊天室的樣例。
這里實現(xiàn)了Mediator和Colleague的一對多的聚合關(guān)系。這種中介者模式才是有意義的使用方式。
UML類圖:
C++代碼例如以下:
#include <iostream>
#include <map>
#include <string>
using namespace std;
class Participant;
class AbstractChatRoom
{
public:
virtual void registe(Participant * p)=0;
virtual void send(string from,string to ,string message)=0;
};
class ChatRoom:public AbstractChatRoom
{
public:
void registe(Participant * p);
void send(string from,string to ,string message);
private:
map<Participant *,string> participants;
};
class Participant
{
public:
Participant(string n=""):name(n)
{
}
string getName()
{
return name;
}
void setChatRoom(ChatRoom *c)
{
chatRoom=c;
}
void send(string to,string message)
{
chatRoom->send(name,to,message);
}
virtual void receive(string from,string message)
{
cout<<from<<" to "<<name<<" : "<<message<<endl;
}
private:
string name;
ChatRoom * chatRoom;
};
void ChatRoom::registe(Participant * p)
{
if(!participants.count(p))
{
participants.insert(pair<Participant *,string>(p,p->getName()));
}
p->setChatRoom(this);
}
void ChatRoom::send(string from,string to ,string message)
{
map<Participant *,string>::iterator iter;
for(iter=participants.begin();iter!=participants.end();iter++)
{
if(iter->second==to)
break;
}
if(iter!=participants.end())
{
iter->first->receive(from,message);
}
}
class Beatle:public Participant
{
public:
Beatle(string n=""):Participant(n)
{
}
void receive(string from,string message)
{
cout<<"to a beatle : ";
Participant::receive(from,message);
}
};
class NonBeatle:public Participant
{
public:
NonBeatle(string n=""):Participant(n)
{
}
void receive(string from,string message)
{
cout<<"to a non-beatle : ";
Participant::receive(from,message);
}
};
int main()
{
cout<<"聊天室中介者模式代碼"<<endl;
ChatRoom * chatRoom=new ChatRoom();
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->registe(george);
chatRoom->registe(paul);
chatRoom->registe(ringo);
chatRoom->registe(john);
chatRoom->registe(yoko);
yoko->send("John","hi John!");
paul->send("Ringo","All you need is love");
ringo->send("George","My sweet Lord");
paul->send("John","can not buy me love");
john->send("Yoko","My sweet love");
return 0;
}
運行輸出:
浙公網(wǎng)安備 33010602011771號