1 概述
中介者模式(Mediator Pattern)是一种行为模式,通过定义一个中介对象,来管理一系列对象之间的依赖,从而解耦原有对象之间的关系。
2 中介者模式
大量的对象相互依赖,会大大增加系统复杂度,提高维护成本。中介者模式(Mediator Pattern)是迪米特原则的一个很好体现,它通过将对象的依赖关系维护在一个中介者中,使原本耦合在一起的对象变得相互独立。 交通信号灯是一个很常见的例子,如果没有信号灯,十字路口的车子必须知道互相之间要去的方向,来决定什么时候踩油门,什么时候踩刹车,如此一来很容易堵车。而信号灯的作用就是中介者,司机们不用关心其他车子,只需按照“红灯停,绿灯行”的规则,按照灯的指示来做行驶。信号灯充当来中介者,维护了交通秩序。
3 案例
让我们来看一个更简单的例子。聊天室提供了群聊的功能,可以增加,删除成员。内部的人员,可以将消息发送给所有的其他人。如果说每个成员内部都维护一个所有成员的列表,直接点对点发送消息,那么当人数很多的时候,整个逻辑会变得很复杂,同时,对于人员的增减,也将是个繁重的工作。现实中我们当然不会这么做,而是通过定义一个ChatRoom
对象,来维护群聊成员列表,同时负责管理消息的发送,看看用中介者模式,如何优雅地设计聊天室:
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
public interface ChatRoom {
void broadcast(String message, Member sender);
void addMember(Member member);
void removeMember(Member member);
}
public class ChatRoomImpl implements ChatRoom {
List<Member> memberList = new ArrayList<>();
@Override
public void broadcast(String message, Member sender) {
for (Member member : memberList) {
if (!member.equals(sender)) {
member.receive(message);
}
}
}
@Override
public void addMember(Member member) {
if (!memberList.contains(member)) {
memberList.add(member);
member.setChatRoom(this);
}
}
@Override
public void removeMember(Member member) {
memberList.remove(member);
}
}
public abstract class Member {
protected ChatRoom chatRoom;
protected String name;
public Member(String name){
this.name=name;
}
public void setChatRoom(ChatRoom chatRoom) {
this.chatRoom = chatRoom;
}
public abstract void send(String message);
public abstract void receive(String message);
}
public class MemberImpl extends Member {
public MemberImpl(String name) {
super(name);
}
@Override
public void send(String message) {
System.out.println(name + " send message: " + message);
chatRoom.broadcast(message, this);
}
@Override
public void receive(String message) {
System.out.println(name + " received message: " + message);
}
}
public class Test {
public static void main(String[] args) {
ChatRoom chatRoom = new ChatRoomImpl();
Member link = new MemberImpl("Link");
Member mario = new MemberImpl("Mario");
Member yoshi = new MemberImpl("Yoshi");
chatRoom.addMember(link);
chatRoom.addMember(mario);
chatRoom.addMember(yoshi);
link.send("Hello");
}
}
输出:
1
2
3
Link send message: Hello
Mario received message: Hello
Yoshi received message: Hello
可以发现,Member
对象之间,无需彼此依赖,甚至都不需要知道彼此之间的存在,所有的关系依赖都维护在ChatRoom
中。对于成员的修改,增减,并不会影响到整个系统。
其实即时通信类的架构模式,都是上述模式的扩展。比如微信中,每个客户端(IOS
/Android
)充当的是Member
角色,他们之间并不直接交互,而是通过腾讯的服务器(ChatRoom
角色),来发送和接收消息。从某种意义上来说,中介者模式是即时通信的基石。
4 总结
中介者模式使得程序更易于修改和扩展。当对象之间的关系/通信很复杂的时候,可以看看,是否可以通过抽象出一个中心点作为中介者,来解耦了对象之间的依赖。