23种设计模式(C++)之 中介者(Mediator)模式
23种设计模式(C++)之 中介者(Mediator)模式
意图
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
适用性
- 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
- 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
- 想定制一个分布在多个类中的行为,而又不想生成太多的子类。
角色
- Mediator
- 中介者定义一个接口用于与各同事(Colleague)对象通信。
- ConcreteMediator
- 具体中介者通过协调各同事对象实现协作行为。
- 了解并维护它的各个同事。
- Colleague Class
- 每个同事类都知道它的中介者对象
- 每个同事对象在需与其他同事通信的时候,与它的中介者通信。
实例
- 创建同事抽象接口
class Mediator;
class Colleague
{
protected:
Mediator* mediator;
string name;
public:
virtual string getName() = 0;
virtual void sendMsg2SomeOne(string msg, string receiverName) = 0;
virtual void receiveMsg(string msg, string senderName) = 0;
};
- 创建具体同事类
class ColleagueA :public Colleague
{
private:
string name;
public:
ColleagueA(string name, Mediator* mediator)
{
this->name = name;
this->mediator = mediator;
}
string getName()
{
return this->name;
}
void sendMsg2SomeOne(string msg, string receiverName);
void receiveMsg(string msg, string senderName)
{
cout << this->name + " received a msg from " + senderName << " and the msg is " << msg << endl;
}
};
class ColleagueB :public Colleague
{
private:
string name;
public:
ColleagueB(string name, Mediator* mediator)
{
this->name = name;
this->mediator = mediator;
}
string getName()
{
return this->name;
}
void sendMsg2SomeOne(string msg, string receiverName);
void receiveMsg(string msg, string senderName)
{
cout << this->name+" received a msg from " + senderName << " and the msg is " << msg << endl;
}
};
- 创建中介者抽象接口
class Mediator
{
public:
virtual void setColleagueA(Colleague* colleagueA) = 0;
virtual void setColleagueB(Colleague* colleagueB) = 0;
virtual void sendMessage(string msg, string receiverName, string senderName) = 0;
};
- 创建具体中介者类
class ConcreteMediator: public Mediator
{
private:
Colleague* colleagueA;
Colleague* colleagueB;
public:
void setColleagueA(Colleague* colleagueA)
{
this->colleagueA = colleagueA;
}
void setColleagueB(Colleague* colleagueB)
{
this->colleagueB = colleagueB;
}
void sendMessage(string msg, string receiverName, string senderName)
{
if (receiverName == this->colleagueA->getName())
{
this->colleagueA->receiveMsg(msg, senderName);
}
else if (receiverName == this->colleagueB->getName())
{
this->colleagueB->receiveMsg(msg, senderName);
}
}
};
void ColleagueA::sendMsg2SomeOne(string msg, string receiverName)
{
this->mediator->sendMessage(msg, receiverName, this->name);
}
void ColleagueB::sendMsg2SomeOne(string msg, string receiverName)
{
this->mediator->sendMessage(msg, receiverName, this->name);
}
- Client
int main()
{
//Create a mediator
Mediator* mediator = new ConcreteMediator();
//Instance each colleague with mediator
Colleague* colleagueA = new ColleagueA("colleagueA", mediator);
Colleague* colleagueB = new ColleagueB("colleagueB", mediator);
//Let mediator know each colleague
mediator->setColleagueA(colleagueA);
mediator->setColleagueB(colleagueB);
//Communicate between colleagues
colleagueA->sendMsg2SomeOne("'Hello, I'm colleagueA!'", colleagueB->getName());
colleagueB->sendMsg2SomeOne("'Hello, I'm colleagueB!'", colleagueA->getName());
}
- 结果
colleagueB received a msg from colleagueA and the msg is 'Hello, I'm colleagueA!'
colleagueA received a msg from colleagueB and the msg is 'Hello, I'm colleagueB!'