Earth Guardian

You are not LATE!You are not EARLY!

0%

设计模式--行为型:中介者模式

中介者模式:用一个中介对象来封装一系列的对象交互。使得各对象不用显式的相互引用,从而使其耦合松散,而且可以独立改变它们之间的交互

中介者模式

中介者模式 Mediator[ˈmidiˌetɚ] Pattern:又称为调停者模式,将多对多的相互作用转换为一对多的相互作用,减少对象间的复杂引用关系,使得成为一个松耦合系统。

类图结构

0065-Mediator-uml-classdiag.png

结构解析

  • Mediator
    抽象类,定义中转调用时的方法。
  • ConcreteMediator
    实现类,实现中转调用的逻辑,持有所有需要被中转类的引用。
  • Colleague
    抽象类,仅仅持有一个抽象 Mediator 对象的引用,不定义抽象方法。
  • ConcreteColleague1/ConcreteColleague2
    实现类,定义需要中转的方法。两者并不需要有公共父类,如果需要也仅仅是引用相同的 Mediator 对象。

客户端会将 ConcreteColleague1, ConcreteColleague2, ConcreteMediator 三个对象连接起来,当 ConcreteColleague1 需要调用 ConcreteColleague2 的方法时,并不是直接调用,而是通过 ConcreteMediator.mediate 来中转调用。
Colleague 这个角色并不一定需要,它的作用仅仅是将实现类和 Mediator 关联起来,持有 Mediator 的引用。所以实际使用中 ConcreteColleague1, ConcreteColleague2 也并不是拥有相同父类,只要将他们通过 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
// 1. Mediator
public abstract class Mediator {
public abstract void mediate();
}

// 2. Colleague
public abstract class Colleague {
protected Mediator mediator;

public Colleague(Mediator mediator) {
this.mediator = mediator;
}
}

// 3. ConcreteColleague
public class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}

public void action1() {
System.out.println("ConcreteColleague1: Coding to implement "
+ "requirement. Please release Version.");
mediator.mediate();
}
}

public class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}

public void action2(){
System.out.println("ConcreteColleague2: Make release version.");
}
}

// 4. ConcreteMediator
public class ConcreteMediator extends Mediator{
private ConcreteColleague1 colleague1;
private ConcreteColleague2 colleague2;

@Override
public void mediate() {
if (colleague2 != null){
colleague2.action2();
}
}

public void setColleague1(ConcreteColleague1 colleague1){
this.colleague1 = colleague1;
}

public void setColleague2(ConcreteColleague2 colleague2) {
this.colleague2 = colleague2;
}
}

// 5. Test
public class TestMediator {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);
mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);

colleague1.action1();
}
}

// 6. Result
ConcreteColleague1: Coding to implement requirement. Please release Version.
ConcreteColleague2: Make release version.

中介者模式中需要中转调用的两个类,并不一定需要有相同的父类。父类 Colleague 更多的是确保每个子类必须持有 Mediator 的引用。如上示例中 ConcreteColleague1.action1ConcreteColleague2.action2 的调用,就是通过 ConcreteMediator.mediate 来实现的。

总结

  • 中介者模式与迪米特原则
    迪米特原则:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某个方法的话,可以通过第三者转发调用。该原则指一个对象应该对于其他对象有最少的了解,有效的降低类之间的耦合。中介者模式是迪米特原则的典型应用。
  • 类比
    中介者模式,类似电脑的主板协调各个器件工作;系统的各个总线协调驱动程序运行;中介者模式能够将错综复杂的网状图优化成结构清晰的星型图,其中心就是中介者;MVC 架构中的 Control 就是典型的中介者。
    所有的 UI 交互系统,如 C#/Form, Android Activity 中的 UI 交互界面,都承担了中介者的角色,它会将 Button, TextView, EditText 等连接起来,这些控件的交互都是通过窗体来中转,响应并显示的。

参考文档

  • 大话设计模式
  • Android 源码设计模式解析与实战
  • 中介者模式