Mediator

中介者

使用中介者模式来集中相关对象之间复杂的沟通和控制方式。
每个对象都会在自己的状态改变时,告诉中介者。
每个对象队徽对中介者所发出的请求做出回应。

适用性

  • 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
  • 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
  • 想定制一个分布在多个类中的行为,而又不想生成太多的子类。

典型情境

智能家居,互相之间规则复杂。
Mediator Scenario

结构

Mediator Class
Mediator Object

Mediator - 中介者定义一个接口用于与各Colleague对象通信。
ConcreteMediator - 具体中介者通过协调各同事对象实现协作行为。了解并维护它的各个同事。
Colleague Class - 每一个同事类都知道它的中介者对象。每一个同事对象在需与其他的同事通信的时候,与它的中介者通信。

协作:
同事向一个中介者发送和接收请求。中介者在各同事间是当地转发请求以实现协作行为。

示例

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
#include <iostream>
class Mediator;
//---------------------------------------------------
class Colleague
{
public:
Colleague(Mediator* m) : m_mediator(m){}
protected:
Mediator* m_mediator;
};
//---------------------------------------------------
class Mediator
{
public:
virtual void process(Colleague* c) = 0;
};
//---------------------------------------------------
class ConcreteColleague1 : public Colleague
{
public:
ConcreteColleague1(Mediator* m) :Colleague(m){}
void step1()
{

std::cout << "Step1" << std::endl;
if (!m_mediator) return;
m_mediator->process(this);
}
void step3()
{

std::cout << "Step3" << std::endl;
}
};
//---------------------------------------------------
class ConcreteColleague2 : public Colleague
{
public:
ConcreteColleague2(Mediator* m) : Colleague(m){}
void step2()
{

std::cout << "Step2" << std::endl;
if (!m_mediator) return;
m_mediator->process(this);
}
};
//---------------------------------------------------
class ConcreteMediator : public Mediator
{
public:
ConcreteMediator() : Mediator(), m_cc1(NULL), m_cc2(NULL)
{
m_cc1 = new ConcreteColleague1(this);
m_cc2 = new ConcreteColleague2(this);
}
virtual void process(Colleague* c)
{

if (!c || !m_cc1 || !m_cc2) return;
if (c == m_cc1)
{
m_cc2->step2();
}else if (c == m_cc2)
{
m_cc1->step3();
}
}
void test_start()
{

if (!m_cc1) return;
m_cc1->step1();
}
protected:
ConcreteColleague1* m_cc1;
ConcreteColleague2* m_cc2;
};
//---------------------------------------------------
int main()
{

ConcreteMediator cm;
cm.test_start();
system("Pause");
}

优点

  • 通过将对象彼此解耦,可以增加对象的可复用性。
  • 通过将控制逻辑集中,可以简化系统维护。
  • 可以让对象之间所传递的消息变得简单而且大幅减少。

用途和缺点

  • 中介者常常被用来协调相关的GUI组件。
  • 中介者模式的缺点是,如果设计不当,中介者对象本身会变得过于复杂。

相关模式

  • Facade与中介者的不同之处在于它是对一个对象子系统进行抽象,从而提供了一个更为方便的接口。它的协议是单向的,即Facade对象对这个子系统类提出请求,但反之则不行。相反,Mediator提供了各Colleague对象不支持或不能支持的协作行为,而且协议是多向的。
  • Colleague可使用Observer模式与Mediator通信。

[1] 设计模式:可复用面向对象软件的基础
[2] Head First设计模式