【设计模式】行为型模式-Mediator模式
# 功能
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互
# 解决
- 主要解决:对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理
- 何时使用:多个类相互耦合,形成了网状结构
- 如何解决:将上述网状结构分离为星型结构
- 关键代码:对象 Colleague 之间的通信封装到一个类中单独处理
# 优缺点
- 优点:
- 降低了类的复杂度,将一对多转化成了一对一
- 各个类之间的解耦
- 符合迪米特原则
- 缺点:中介者会庞大,变得复杂难以维护
# 应用场景
- 应用实例:
- 中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易
- 机场调度系统
- MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者
- 使用场景:
- 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类
- 注意事项:不应当在职责混乱的时候使用
# 简单示例代码部分
Mediator.hpp
#ifndef _MEDIATOR_H_
#define _MEDIATOR_H_
#include <string>
#include <iostream>
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){
this->_mdt=mdt;
}
Mediator* _mdt;
};
class ConcreteColleageA:public Colleage{
public:
ConcreteColleageA(){}
ConcreteColleageA(Mediator* mdt):Colleage(mdt){}
~ConcreteColleageA(){}
void Aciton();
void SetState(const string& sdt){
_sdt=sdt;
}
string GetState(){
return _sdt;
}
private:
string _sdt;
};
class ConcreteColleageB:public Colleage {
public:
ConcreteColleageB(){}
ConcreteColleageB(Mediator* mdt):Colleage(mdt){}
~ConcreteColleageB(){}
void Aciton();
void SetState(const string& sdt){
_sdt=sdt;
}
string GetState(){
return _sdt;
}
private:
string _sdt;
};
class Mediator {
public:
virtual ~Mediator(){}
virtual void DoActionFromAtoB() = 0;
virtual void DoActionFromBtoA() = 0;
protected:
Mediator(){}
};
class ConcreteMediator:public Mediator {
public:
ConcreteMediator(){}
ConcreteMediator(Colleage* clgA,Colleage* clgB){
this->_clgA=clgA;
this->_clgB=clgB;
}
~ConcreteMediator(){}
void SetConcreteColleageA(Colleage* clgA){
this->_clgA = clgA;
}
void SetConcreteColleageB(Colleage* clgB){
this->_clgB = clgB;
}
Colleage* GetConcreteColleageA(){
return _clgA;
}
Colleage* GetConcreteColleageB(){
return _clgB;
}
void IntroColleage(Colleage* clgA,Colleage* clgB){
this->_clgA = clgA;
this->_clgB = clgB;
}
void DoActionFromAtoB(){
_clgB->SetState(_clgA->GetState());
}
void DoActionFromBtoA(){
_clgA->SetState(_clgB->GetState());
}
private:
Colleage* _clgA;
Colleage* _clgB;
};
void ConcreteColleageA::Aciton(){
_mdt->DoActionFromAtoB();
cout<<"State of ConcreteColleageA:"<<" "<<this->GetState()<<endl;
}
void ConcreteColleageB::Aciton(){
_mdt->DoActionFromBtoA();
cout<<"State of ConcreteColleageB:"<<" "<<this->GetState()<<endl;
}
#endif
1
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
main.cpp
#include "Mediator.h"
#include <iostream>
using namespace std;
int main() {
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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
编辑 (opens new window)
上次更新: 2022/05/18, 15:47:37