中介者模式
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
示例代码
- 由于两个类相互引用,故需要分文件声明定义
//mediator.h文件
#include <string>
using namespace std;
class Colleague;
//Mediator 是抽象中介者,定义了同事对象到中介者对象的接口
class Mediator
{
public:
//定义一个抽象的发送消息方法,得到同事对象和发送信息
virtual void Send(string message, Colleague *colleague) = 0;
};
//colleague.h文件
#include "mediator.h"
//- Colleague 叫做抽象同事类
class Colleague
{
public:
//构造方法,得到中介者对象
Colleague(Mediator *mediator) :m_mediator(mediator){}
protected:
Mediator *m_mediator;
};
//中介者模式
//两个抽象类要分文件声明定义
//ConcreteCollgague 具体同事类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但它们都认识中介者对象。
class ConcreteCollgague1 :public Colleague
{
public:
ConcreteCollgague1(Mediator *mediator) :Colleague(mediator){}
void Send(string message){ m_mediator->Send(message, this); }
void Notify(string message){ cout << "同事1得到消息:" << message << endl; }
};
class ConcreteCollgague2 :public Colleague
{
public:
ConcreteCollgague2(Mediator *mediator) :Colleague(mediator){}
void Send(string message){ m_mediator->Send(message, this); }
void Notify(string message){ cout << "同事2得到消息:" << message << endl; }
};
//ConcreteMediator 是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事类接收消息,向具体同事对象发出命令。
class ConcreteMediator :public Mediator
{
public:
void SetColleague1(ConcreteCollgague1 *colleague1){ m_colleague1 = colleague1; }
void SetColleague2(ConcreteCollgague2 *colleague2){ m_colleague2 = colleague2; }
void Send(string message, Colleague *colleague)
{
if (colleague == m_colleague1)
{
m_colleague2->Notify(message);
}
else
{
m_colleague1->Notify(message);
}
}
private:
ConcreteCollgague1 *m_colleague1;
ConcreteCollgague2 *m_colleague2;
};
}
测试程序:
int main()
{
ConcreteMediator *mediator = new ConcreteMediator;
ConcreteCollgague1 *c1 = new ConcreteCollgague1(mediator);
ConcreteCollgague2 *c2 = new ConcreteCollgague2(mediator);
mediator->SetColleague1(c1);
mediator->SetColleague2(c2);
c1->Send("在么?");
c2->Send("在的,什么事?");
c1->Send("没事,关心关心你");
c2->Send("谢谢");
system("pause");
return 0;
}
运行结果:
当在同一个文件中定义两个不同的类,且在两个类中相互引用,这样编译是通不过的
A和B的定义和调用都放在一个文件中,这样就会造成两个循环调用的死循环。
根本原因是:定义A的时候,A的里面有B,所以就需要去查看B的占空间大小,但是查看的时候又发现需要知道A的占空间大小,造成死循环。
C++中两个类互相引用的解决方法
写两个头文件A.h和B.h分别用于声明类A和B;
写两个.cpp文件分别用于定义类A和B;
在A的头文件中导入B的头文件;
在B的头文件中不导入A的头文件,但是用extern 的方式声明类A,并且,在B中使用A的时候要用指针的形式。