行为型 - 中介者(Mediator)
中介者模式(Mediator pattern) : 使用中介者模式来集中相关对象之间复杂的沟通和控制方式。
概念
Mediator 模式典型的结构图为:
Mediator 模式中,每个 Colleague 维护一个 Mediator,当要进行交互,例如图中ConcreteColleagueA 和 ConcreteColleagueB 之间的交互就可以通过 ConcreteMediator 提供的DoActionFromAtoB 来处理, ConcreteColleagueA 和 ConcreteColleagueB 不必维护对各自的引用,甚至它们也不知道各个的存在。 Mediator 通过这种方式将多对多的通信简化为了一( Mediator) 对多( Colleague)的通信。
代码实现
#ifndef _COLLEAGE_H_
#define _COLLEAGE_H_
#include <string>
using namespace std;
class Mediator;
class Colleage
{
public:
virtual ~Colleage();
virtual void Aciton() = 0;
virtual void SetState(const string &sdt) = 0;
virtual string GetState() = 0;
protected:
Colleage();
Colleage(Mediator *mdt);
Mediator *_mdt;
private:
};
class ConcreteColleageA : public Colleage
{
public:
ConcreteColleageA();
ConcreteColleageA(Mediator *mdt);
~ConcreteColleageA();
void Aciton();
void SetState(const string &sdt);
string GetState();
protected:
private:
string _sdt;
};
class ConcreteColleageB : public Colleage
{
public:
ConcreteColleageB();
ConcreteColleageB(Mediator *mdt);
~ConcreteColleageB();
void Aciton();
void SetState(const string &sdt);
string GetState();
protected:
private:
string _sdt;
};
#endif //~_COLLEAGE_H_
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "Mediator.h"
#include "Colleage.h"
#include <iostream>
using namespace std;
Colleage::Colleage()
{
}
Colleage::Colleage(Mediator *mdt)
{
this->_mdt = mdt;
}
Colleage::~Colleage()
{
}
ConcreteColleageA::ConcreteColleageA()
{
}
ConcreteColleageA::~ConcreteColleageA()
{
}
ConcreteColleageA::ConcreteColleageA(Mediator *mdt) : Colleage(mdt)
{
}
string ConcreteColleageA::GetState()
{
return _sdt;
}
void ConcreteColleageA::SetState(const string &sdt)
{
_sdt = sdt;
}
void ConcreteColleageA::Aciton()
{
_mdt->DoActionFromAtoB();
cout << "State of ConcreteColleageA: " << this->GetState() << endl;
}
ConcreteColleageB::ConcreteColleageB()
{
}
ConcreteColleageB::~ConcreteColleageB()
{
}
ConcreteColleageB::ConcreteColleageB(Mediator *mdt) : Colleage(mdt)
{
}
void ConcreteColleageB::Aciton()
{
_mdt->DoActionFromBtoA();
cout << "State of ConcreteColleageB: " << this->GetState() << endl;
}
string ConcreteColleageB::GetState()
{
return _sdt;
}
void ConcreteColleageB::SetState(const string &sdt)
{
_sdt = sdt;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef _MEDIATOR_H_
#define _MEDIATOR_H_
class Colleage;
class Mediator
{
public:
virtual ~Mediator();
virtual void DoActionFromAtoB() = 0;
virtual void DoActionFromBtoA() = 0;
protected:
Mediator();
private:
};
class ConcreteMediator : public Mediator
{
public:
ConcreteMediator();
ConcreteMediator(Colleage *clgA, Colleage *clgB);
~ConcreteMediator();
void SetConcreteColleageA(Colleage *clgA);
void SetConcreteColleageB(Colleage *clgB);
Colleage *GetConcreteColleageA();
Colleage *GetConcreteColleageB();
void IntroColleage(Colleage *clgA, Colleage *clgB);
void DoActionFromAtoB();
void DoActionFromBtoA();
protected:
private:
Colleage *_clgA;
Colleage *_clgB;
};
#endif //~_MEDIATOR_H
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "Mediator.h"
#include "Colleage.h"
Mediator::Mediator()
{
}
Mediator::~Mediator()
{
}
ConcreteMediator::ConcreteMediator()
{
}
ConcreteMediator::~ConcreteMediator()
{
}
ConcreteMediator::ConcreteMediator(Colleage *clgA, Colleage *clgB)
{
this->_clgA = clgA;
this->_clgB = clgB;
}
void ConcreteMediator::DoActionFromAtoB()
{
_clgB->SetState(_clgA->GetState());
}
void ConcreteMediator::SetConcreteColleageA(Colleage *clgA)
{
this->_clgA = clgA;
}
void ConcreteMediator::SetConcreteColleageB(Colleage *clgB)
{
this->_clgB = clgB;
}
Colleage *ConcreteMediator::GetConcreteColleageA()
{
return _clgA;
}
Colleage *ConcreteMediator::GetConcreteColleageB()
{
return _clgB;
}
void ConcreteMediator::IntroColleage(Colleage *clgA, Colleage *clgB)
{
this->_clgA = clgA;
this->_clgB = clgB;
}
void ConcreteMediator::DoActionFromBtoA()
{
_clgA->SetState(_clgB->GetState());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "Mediator.h"
#include "Colleage.h"
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
ConcreteMediator *m = new ConcreteMediator();
ConcreteColleageA *c1 = new ConcreteColleageA(m);
ConcreteColleageB *c2 = new ConcreteColleageB(m);
m->IntroColleage(c1, c2);
c1->SetState("old");
c2->SetState("old");
c1->Aciton();
c2->Aciton();
cout << endl;
c1->SetState("new");
c1->Aciton();
c2->Aciton();
cout << endl;
c2->SetState("old");
c2->Aciton();
c1->Aciton();
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@VM-16-6-centos Mediator]# ./MediatorTest
State of ConcreteColleageA: old
State of ConcreteColleageB: old
State of ConcreteColleageA: new
State of ConcreteColleageB: new
State of ConcreteColleageB: old
State of ConcreteColleageA: old
2
3
4
5
6
7
8
9
代码说明
Mediator 模式的实现关键就是将对象 Colleague 之间的通信封装到一个类种单独处理,为了模拟 Mediator 模式的功能,这里给每个 Colleague 对象一个 string 型别以记录其状态,并通过状态改变来演示对象之间的交互和通信。这里主要就 Mediator 的示例运行结果给出
分析:
- 将 ConcreteColleageA 对象设置状态“ old”, ConcreteColleageB 也设置状态“ old”;
- ConcreteColleageA 对象改变状态,并在 Action 中和 ConcreteColleageB 对象进行通信,并改变ConcreteColleageB 对象的状态为“ new”;
- ConcreteColleageB 对象改变状态,并在 Action 中和 ConcreteColleageA 对象进行通信,并改变ConcreteColleageA 对象的状态为“ old”;
注意到,两个 Colleague 对象并不知道它交互的对象,并且也不是显示地处理交互过程,这一切都是通过 Mediator 对象完成的,示例程序运行的结果也正是证明了这一点。
讨论
Mediator 模式是一种很有用并且很常用的模式,它通过将对象间的通信封装到一个类中,将多对多的通信转化为一对多的通信, 降低了系统的复杂性(有点类似消息队列)。 Mediator 还获得系统解耦的特性,通过 Mediator,各个 Colleague 就不必维护各自通信的对象和通信协议,降低了系统的耦合性, Mediator 和各个 Colleague 就可以相互独立地修改了。Mediator 模式还有一个很显著额特点就是将控制集中,集中的优点就是便于管理,也正式符合了 OO 设计中的每个类的职责要单一和集中的原则