中介者模式

假设这样的场景:我们有很多的类,各个类之间需要彼此通信,那么每个类都需要直到其他的类存在和接口,如果类特别多,相互之间的耦合关系就会特别复杂。这种关系在现实中可以找到很多例子,比如一个班所有同学的关系,一个办公室同事的关系等等。

中介者模式就是用于解决类似的问题,比如在一个班级里,同学之间不之间进行沟通,而是选出一个代表作为中间人,当张三要发布一条消息时,他只管将消息告诉中间人,其他的由中间人来处理,同样的,李四要发布一条消息也和中间人对接。通过引入了一个中间人,张三和李四都不必了解怎么去和其他同学通信,只要中间人知道就行了,这就是中介者模式的思想。

代码设计

在面向对象设计中,通过引入中间层是比较常规的做法,以下是中介者模式的设计图,抽象类object定义了接口,并保存中介者指针,中介者同时保存所有object的指针。在实际中,也可以把mediator抽象为接口,但是mediator也只有一个类,感觉用处不大。

中介者模式

代码实现

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
#include <list>

class Object;

class Mediator {
public:
void Send(const char* msg, Object* sender);
void Register(Object* ob);
private:
std::list<Object*> objects_;
};

class Object {
public:
Object(Mediator* m) : mediator_(m) { mediator_->Register(this); }
virtual void Send(const char* msg) = 0;
virtual void Receive(const char* msg) = 0;
protected:
Mediator* mediator_;
};

class ObjectX : public Object {
public:
ObjectX(Mediator* m) : Object(m) {}
virtual void Send(const char* msg) override {
mediator_->Send(msg, this);
}
virtual void Receive(const char* msg) override {
printf("X::A msg received: %s\n", msg);
}
};

class ObjectY : public Object {
public:
ObjectY(Mediator* m) : Object(m) {}
virtual void Send(const char* msg) override {
mediator_->Send(msg, this);
}
virtual void Receive(const char* msg) override {
printf("Y::A msg received: %s\n", msg);
}
};

class ObjectZ : public Object {
public:
ObjectZ(Mediator* m) : Object(m) {}
virtual void Send(const char* msg) override {
mediator_->Send(msg, this);
}
virtual void Receive(const char* msg) override {
printf("Z::A msg received: %s\n", msg);
}
};

void Mediator::Send(const char* msg, Object* sender) {
for (auto ob : objects_) {
if (ob != sender) {
ob->Receive(msg);
}
}
}
void Mediator::Register(Object* ob) {
objects_.push_back(ob);
}

int main() {
Mediator mediator;
ObjectX x(&mediator);
ObjectY y(&mediator);
ObjectZ z(&mediator);

x.Send("Today is good day");
y.Send("Today is good day");
z.Send("Today is good day");

getchar();
return 0;
}