当我们有N个类需要互相沟通时,一对一的方式建立的连接数量为 N*(N-)/2 ,耦合性太高。我们应该建立一个中间节点,所有人通过这个中间节点来进行沟通,这就是中介者模式

比如国家与国家间进行交流时,建立一个联合国,大家通过这个中间人来发表声明,这时我们先抽象出一个国家基类,它定义了与中间者联合国交流的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class UnitedNation;
class AbstructCountry {
public:

virtual void sendMsg(Country target, std::string msg) = 0;
virtual void GetMsg(Country from, std::string msg) = 0;
virtual ~AbstructCountry() {}
void SetUnion(UnitedNation *u) {
m_u = u;
}
Country m_c;
protected:
UnitedNation* m_u;
};

联合国类提供一个接受消息的接口,以及addMember函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class UnitedNation {
public:
void addMember(AbstructCountry* country) {
m_members[country->m_c] = country;
country->SetUnion(this);
}

void PushMsg(Country from, Country to, std::string msg) {
if(to == Country::ALL) {
for(auto &item : m_members) {
if(item.first == from) {
continue;
}
item.second->GetMsg(from, msg);
}
} else {
m_members[to]->GetMsg(from, msg);
}
}
private:
std::unordered_map<Country, AbstructCountry*> m_members;
};

此时,每个国家类都可以继承 AbstructCountry ,重写发送消息和接受消息的接口,发送消息要把声明传递给联合国对象 m_u。

整体代码如下

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <csignal>
#include <iostream>
#include <string>
#include <cstdint>
#include <unordered_map>

enum class Country : uint8_t {
CN,
RU,
US,
ALL,
};

std::string enum2str(Country c) {
switch (c) {
case Country::CN:
return "中国";
case Country::RU:
return "俄罗斯";
case Country::US:
return "美国";
case Country::ALL:
return "所有与会国";
}
}

class UnitedNation;
class AbstructCountry {
public:

virtual void sendMsg(Country target, std::string msg) = 0;
virtual void GetMsg(Country from, std::string msg) = 0;
virtual ~AbstructCountry() {}
void SetUnion(UnitedNation *u) {
m_u = u;
}
Country m_c;
protected:
UnitedNation* m_u;
};

class UnitedNation {
public:
void addMember(AbstructCountry* country) {
m_members[country->m_c] = country;
country->SetUnion(this);
}

void PushMsg(Country from, Country to, std::string msg) {
if(to == Country::ALL) {
for(auto &item : m_members) {
if(item.first == from) {
continue;
}
item.second->GetMsg(from, msg);
}
} else {
m_members[to]->GetMsg(from, msg);
}
}
private:
std::unordered_map<Country, AbstructCountry*> m_members;
};

class China : public AbstructCountry {
public:
China(){
m_c = Country::CN;
}
void sendMsg(Country target, std::string msg) override {
std::cout << "中国向" << enum2str(target) << "发表声明:" << msg << std::endl;
m_u->PushMsg(m_c, target, msg);
}

void GetMsg(Country from, std::string msg) override {
std::cout << "中国收到来自" << enum2str(from) << "的声明:" << msg << std::endl;
}
};
class Russia : public AbstructCountry {
public:
Russia() {
m_c = Country::RU;
}
void sendMsg(Country target, std::string msg) override {
std::cout << "俄罗斯向" << enum2str(target) << "发表声明:" << msg << std::endl;
m_u->PushMsg(m_c, target, msg);
}

void GetMsg(Country from, std::string msg) override {
std::cout << "俄罗斯收到来自" << enum2str(from) << "的声明:" << msg << std::endl;
}
};
class USA : public AbstructCountry {
public:
USA() {
m_c = Country::US;
}
void sendMsg(Country target, std::string msg) override {
std::cout << "美国向" << enum2str(target) << "发表声明:" << msg << std::endl;
m_u->PushMsg(m_c, target, msg);
}

void GetMsg(Country from, std::string msg) override {
std::cout << "美国收到来自" << enum2str(from) << "的声明:" << msg << std::endl;
}
};

int main() {
UnitedNation un;
AbstructCountry* cn = new China();
AbstructCountry* ru = new Russia();
AbstructCountry* us = new USA();

un.addMember(cn);
un.addMember(ru);
un.addMember(us);

std::cout << "==========================" << std::endl;
us->sendMsg(Country::ALL, "我要制裁俄罗斯");
std::cout << "==========================" << std::endl;
us->sendMsg(Country::CN, "你不要购买俄罗斯的商品");
std::cout << "==========================" << std::endl;
cn->sendMsg(Country::ALL, "希望世界和平");
std::cout << "==========================" << std::endl;
ru->sendMsg(Country::US, "放马过来");

delete cn;
delete ru;
delete us;
return 0;
}