中介者模式

概念

用一个中介者对象来封装一系列对象的交互。中介者使个对象不需要显示的互相引用,从而使其耦合松散,而且可以独立第改变他们之间的交互。

中介者模式是封装了一系列的对象交互的成熟模式,其关键是将对象之间的交互封装在称作中介者的对象中,中介者使每个对象不需要显示的相互引用,这些对象只包括中介者的引用。当系统中某个对象需要和系统中的另一个对象进行交互的时候,只需要将自己的请求通知中介者即可。

结构与使用

  • 中介者(Mediator):中介者是一个接口,该接口定义了用于同事(Colleague)对象之间进行通信的方法。

  • 具体中介者(ConcreteMediator):具体中介者是实现中介者接口的类。具体中介者需要包含所有具体同事的引用,并通过实现中介者接口中的方法来满足具体同事之间的通信请求。

  • 同事(Colleague):一个接口,规定具体同事需要实现的方法。

  • 具体同事(ConcreteColleague):实现同事接口的类。具体同事需要包含具体中介者的引用,一个具体同事需要和其他具体同事交互时,只需将自己的请求通知给它所包含的具体中介者即可。

UML类图

Mediator.jpg

结构的描述

以下通过一个简单的例子来描述中介者模式中所涉及的各个角色。

古代相互交战的 A、B、C 三方,想通过一个中介者调停之间的战火。A、B、C 三方分别需要中介者向其他两方传达信息。

1.同事

本问题中同事接口定义了具体同事,即交战双方需要实现的方法。

1
2
3
4
5
6
public interface Colleague {
public void giveMess(String [] mess);
public void receiverMess(String mess);
public void setName(String name);
public String getName();
}

2.具体中介者

本问题中并不需要中介者接口。

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
public class ConcreteMediator {
ColleagueA colleagueA;
ColleagueB colleagueB;
ColleagueC colleagueC;
public void registerColleagueA(ColleagueA colleagueA) {
this.colleagueA = colleagueA;
}
public void registerColleagueB(ColleagueB colleagueB) {
this.colleagueB = colleagueB;
}
public void registerColleagueC(ColleagueC colleagueC) {
this.colleagueC = colleagueC;
}
public void deliverMess(Colleague colleague, String[] mess) {
if (colleague == colleagueA) {
colleagueB.receiverMess(colleague.getName() + mess[0]);
colleagueC.receiverMess(colleague.getName() + mess[1]);
} else if (colleague == colleagueB) {
colleagueA.receiverMess(colleague.getName() + mess[0]);
colleagueC.receiverMess(colleague.getName() + mess[1]);
} else if (colleague == colleagueC) {
colleagueA.receiverMess(colleague.getName() + mess[0]);
colleagueB.receiverMess(colleague.getName() + mess[1]);
}
}
}

3.具体同事

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
// ColleagueA.java
public class ColleagueA implements Colleague {
ConcreteMediator mediator;
String name;
public ColleagueA(ConcreteMediator mediator) {
this.mediator = mediator;
mediator.registerColleagueA(this);
}
@Override
public void giveMess(String[] mess) {
mediator.deliverMess(this, mess);
}
@Override
public void receiverMess(String mess) {
System.out.println(name+"收到的信息:");
System.out.println("\t" + mess);
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}

// ColleagueB.java
public class ColleagueB implements Colleague {
ConcreteMediator mediator;
String name;
public ColleagueB(ConcreteMediator mediator) {
this.mediator = mediator;
mediator.registerColleagueB(this);
}
@Override
public void giveMess(String[] mess) {
mediator.deliverMess(this, mess);
}
@Override
public void receiverMess(String mess) {
System.out.println(name+"收到的信息:");
System.out.println("\t" + mess);
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}

// ColleagueC.java
public class ColleagueC implements Colleague {
ConcreteMediator mediator;
String name;
public ColleagueC(ConcreteMediator mediator) {
this.mediator = mediator;
mediator.registerColleagueC(this);
}
@Override
public void giveMess(String[] mess) {
mediator.deliverMess(this, mess);
}
@Override
public void receiverMess(String mess) {
System.out.println(name+"收到的信息:");
System.out.println("\t" + mess);
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}

4.模式的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String args[]){
ConcreteMediator mediator = new ConcreteMediator();
ColleagueA colleagueA = new ColleagueA(mediator);
ColleagueB colleagueB = new ColleagueB(mediator);
ColleagueC colleagueC = new ColleagueC(mediator);
colleagueA.setName("A国");
colleagueB.setName("B国");
colleagueC.setName("C国");
String[] messA = {"要求归还曾抢夺的100斤土豆", "要求归还曾抢夺的10头牛"};
colleagueA.giveMess(messA);
String[] messB = {"要求归还曾抢夺的10只公鸡", "要求归还曾抢夺的15匹马"};
colleagueB.giveMess(messB);
String[] messC = {"要求归还曾抢夺的300斤小麦", "要求归还曾抢夺的50头驴"};
colleagueC.giveMess(messC);
}

优点

  • 可以避免许多的对象为了之间的相互通信而相互的显示引用。

  • 可以通过中介者将原本分布于多个对象之间的交互行为集中在一起。当这些对象之间需要改变之间的通信行为时,只需使用一个具体中介者即可,不必修改具体同事的代码,即这些同事可被重用。

  • 具体中介者使得各个具体同事完全解耦,修改任何一个具体同事的代码不会影响到其他同事。

  • 具体中介者集中了同事之间的交互细节,使用户比较清楚地知道整个系统中的同事是如何交互的。

注: 由于具体中介者集中了同事之间如何交互的细节,可能使具体中介者变得复杂,增加了维护难度。

欢迎关注我的其它发布渠道