上一篇用一个例子程序来说明程序中可能会出现的类间关系过于复杂,而导致程序的结构变差的情况。这一章的目的就是说明如何使用Mediator模式来解决这个问题。
在看实际的代码之前,我们先了解一下为什么Mediator模式能够解决这些问题。问题的所在就是类之间被互相引用而导致混乱,这显然就是多对多的关系(这就是Mediator使用的语境),我们要解决混乱,就要把他们的关系简化为一对多的关系。充当这个角色的就是Mediator。就好象一班人在打架,你打我,我打你,场面十分混乱,这个时候出来一个人为他们做调解,这个人就是我们的Mediator了。:)
好了,我们首先在程序中写一个Mediator的类:
// Mediator.H
#define _MEDIATOR_H
class A;
class B;
class C;
class Mediator
{
public:
Mediator(A *a, B *b, C *c);
void ACallB();
void ACallC();
void BCallA();
void BCallC();
void CCallA();
void CCallB();
private:
A *_a;
B *_b;
C *_c;
} ;
#endif
// Mediator.CPP
using namespace std;
#include " a.h "
#include " b.h "
#include " c.h "
#include " Mediator.h "
Mediator::Mediator(A * a, B * b, C * c)
{
_a = a;
_b = b;
_c = c;
}
void Mediator::ACallB()
{
cout << "A call ";
_b->Function();
}
void Mediator::ACallC()
{
cout << "A call ";
_c->Function();
}
void Mediator::BCallA()
{
cout << "B call ";
_a->Function();
}
void Mediator::BCallC()
{
cout << "B call ";
_c->Function();
}
void Mediator::CCallA()
{
cout << "C call ";
_a->Function();
}
void Mediator::CCallB()
{
cout << "C call ";
_b->Function();
}
void main()
{
A a;
B b;
C c;
Mediator m(&a, &b, &c);
a.SetMediator(&m);
b.SetMediator(&m);
c.SetMediator(&m);
a.ACallB();
a.ACallC();
b.BCallA();
b.BCallC();
c.CCallA();
c.CCallB();
}
我们看到,main() 函数写在 Mediator.CPP 中,里面的调用基本上和上一篇的调用一样,唯一不同的是多了Mediator对象的加入。a、b、c 三个对象也不需要设置两个协助者了,只需要设置一个Mediator就行了,而调用和上篇完全一样(当然在内部实现是不一样的,但在接口的看来,它们是没什么变化的),这样就把三个类之间复杂的关系解开了。
我们再看看其他三个类的变化,先看看类A,其余两个是差不多的。
// A.H
#define _A_H
class B;
class C;
class Mediator;
class A
{
public:
void SetMediator(Mediator *m);
void ACallB();
void ACallC();
void Function();
private:
B *_b;
C *_c;
Mediator *_m;
} ;
#endif
// A.CPP
#include " b.h "
#include " c.h "
#include " Mediator.h "
#include < iostream >
using namespace std;
void A::SetMediator(Mediator * m)
{
_m = m;
}
void A::ACallB()
{
_m->ACallB();
}
void A::ACallC()
{
_m->ACallC();
}
void A::Function()
{
cout << "A's Func!" << endl;
}
可以看看类A中原来调用其他类的服务,现在都变成了调用 Mediator 中的服务了,再看看 Mediator 的实现,就应该会明白这个模式的思想所在了。
下面再看看其他两个类的实现:
// B.H
#define _B_H
class A;
class C;
class Mediator;
class B
{
public:
void SetMediator(Mediator *m);
void BCallA();
void BCallC();
void Function();
private:
A *_a;
C *_c;
Mediator *_m;
} ;
#endif
// B.CPP
#include " b.h "
#include " c.h "
#include " Mediator.h "
#include < iostream >
using namespace std;
void B::SetMediator(Mediator * m)
{
_m = m;
}
void B::BCallA()
{
_m->BCallA();
}
void B::BCallC()
{
_m->BCallC();
}
void B::Function()
{
cout << "B's Func!" << endl;
}
// C.H
#define _C_H
class A;
class B;
class Mediator;
class C
{
public:
void SetMediator(Mediator *m);
void CCallA();
void CCallB();
void Function();
private:
A *_a;
B *_b;
Mediator *_m;
} ;
#endif
// C.CPP
#include " b.h "
#include " c.h "
#include " Mediator.h "
#include < iostream >
using namespace std;
void C::SetMediator(Mediator * m)
{
_m = m;
}
void C::CCallA()
{
_m->CCallA();
}
void C::CCallB()
{
_m->CCallB();
}
void C::Function()
{
cout << "C's Func!" << endl;
}
我们可以看到,一二两篇代码的执行结果完全相同,但使用了Mediator模式之后,原来在各个对象内部所做的事情,现在全部移交到Mediator里了。也就是将分布在各个对象里面的协议处理过程,全部统一放在Mediator里去做了。骤看来,好像我们是把职责转移了,但是对于代码逻辑的清晰却有很大的好处,这个模式让我们能专注于各个对象之间的交互(他们的交互都放在Mediator类里去做了)。
我们还可以看出,Mediator的核心思想就是把错综复杂的类间的关系独立出来,使得他们的关系清晰化。这样做的
好处是如果类间的交互协议有变化,则只修改Mediator类就行了,但是它的缺点也在于Mediator类,因为所有的
交互都转移到Mediator中,他的复杂性可想而知,搞不好会变成一个庞然大物,难以维护。
这里还是希望大家能动手实现一下,由于关系有点乱,没办法做到傻瓜式的简单。我考虑过如果使用两个
对象来演示又太简单,收不到应有的效果,使用三个对象又会很难描述,所以还是希望大家仿照这两个例子,
动手实现一下,只要你在机器上编完这两个例子(或者你自己突发奇想的例子),然后再思考一下,一定会对Mediator模式有个清晰的认识!