设计模式之中介者模式

1. 概述

中介者模式是一种行为型设计模式,它用一个中介对象来封装一系列的对象交互。 中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 中介者模式的核心思想是将对象间的复杂网状关系转换为星型关系,由中介者负责协调对象间的交互。

2. 适用场景

  • 一组对象以复杂的方式相互关联,导致关系难以理解和维护时。 中介者模式可以将这些对象之间的交互逻辑集中管理。
  • 对象之间的交互行为可以被抽象和集中化时。 如果对象之间的交互行为是多变的,那么使用中介者模式可以方便地修改和扩展这些交互行为。
  • 需要对一组对象之间的交互进行统一控制时。 例如,在图形界面中,多个控件之间的联动关系可以使用中介者模式来管理。
  • 当一个对象修改需要通知其他对象,但是不希望直接依赖其他对象时。 例如,在一个团队协作工具中,当一个成员修改了任务状态,需要通知其他成员,可以使用中介者模式来实现。

3. 模式作用

  • 降低耦合度: 中介者模式通过将对象之间的直接引用改为通过中介者进行间接引用,降低了对象之间的耦合度。 这使得系统更容易修改和扩展。
  • 集中控制交互: 中介者模式将对象之间的交互集中到一个中介者对象中进行管理,使得系统更加易于维护和扩展。 可以方便地对交互逻辑进行修改和扩展。
  • 符合单一职责原则: 每个对象只需要关注自己的职责,而不需要关心与其他对象的交互。 对象之间的交互逻辑由中介者负责。
  • 简化系统结构: 将多对多的复杂关系简化为一对多的关系,降低了系统的复杂性。
  • 提高可复用性: 将对象之间的交互逻辑提取到中介者中,使得对象可以更容易地在其他场景中复用。

4. 代码示例

场景

以一个简单的聊天室为例。 聊天室中有多个用户,用户之间可以通过聊天室进行消息传递. 我们可以使用中介者模式来管理用户之间的交互,用户不需要直接与其他用户通信,而是通过聊天室中介者来发送和接收消息。

代码实现

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
81
82
import java.util.ArrayList;
import java.util.List;

// 1. 中介者 (Mediator) 接口
interface ChatRoomMediator {
void sendMessage(String message, User user);
void addUser(User user);
}

// 2. 具体中介者 (Concrete Mediator) 类
class ChatRoom implements ChatRoomMediator {
private final List<User> users;

public ChatRoom() {
this.users = new ArrayList<>();
}

@Override
public void sendMessage(String message, User user) {
for (User u : this.users) {
// 消息不发给自己
if (u != user) {
u.receive(message);
}
}
}

@Override
public void addUser(User user) {
this.users.add(user);
}
}

// 3. 抽象同事类 (Abstract Colleague)
abstract class User {
protected ChatRoomMediator mediator;
protected String name;

public User(ChatRoomMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}

public abstract void send(String message);
public abstract void receive(String message);
}

// 4. 具体同事类 (Concrete Colleague)
class ChatUser extends User {
public ChatUser(ChatRoomMediator mediator, String name) {
super(mediator, name);
}

@Override
public void send(String message) {
System.out.println(this.name + " 发送消息: " + message);
mediator.sendMessage(message, this);
}

@Override
public void receive(String message) {
System.out.println(this.name + " 接收消息: " + message);
}
}

// 5. 客户端代码 (演示)
public class MediatorPatternDemo {
public static void main(String[] args) {
ChatRoomMediator chatRoom = new ChatRoom();

User user1 = new ChatUser(chatRoom, "张三");
User user2 = new ChatUser(chatRoom, "李四");
User user3 = new ChatUser(chatRoom, "王五");

chatRoom.addUser(user1);
chatRoom.addUser(user2);
chatRoom.addUser(user3);

user1.send("大家好!");
user2.send("你好,张三!");
}
}

5. 运行结果

1
2
3
4
5
6
张三 发送消息: 大家好!
李四 接收消息: 大家好!
王五 接收消息: 大家好!
李四 发送消息: 你好,张三!
张三 接收消息: 你好,张三!
王五 接收消息: 你好,张三!

关键点说明:

  1. ChatRoomMediator (中介者接口):

    • 定义了中介者需要实现的方法:sendMessage() 用于发送消息,addUser() 用于添加用户。 中介者接口定义了同事对象之间交互的接口。
  2. ChatRoom (具体中介者类):

    • ChatRoom 实现了 ChatRoomMediator 接口。 具体中介者类实现了中介者接口,并负责协调同事对象之间的交互。
    • sendMessage() 方法负责将消息发送给聊天室中的其他用户。 该方法遍历所有用户,并将消息发送给除了发送者之外的所有用户。
    • addUser() 方法用于将用户添加到聊天室中。 该方法将用户添加到内部维护的用户列表中。
    • 维护了一个 List<User> 来管理聊天室中的用户。 该列表用于存储所有参与聊天的用户对象。
  3. User (抽象同事类):

    • User 是一个抽象类,定义了用户的基本属性和方法。 抽象同事类定义了所有具体同事类的通用接口。
    • send() 方法用于发送消息。 该方法由具体同事类实现,用于发送消息。
    • receive() 方法用于接收消息。 该方法由具体同事类实现,用于接收消息。
    • 持有 ChatRoomMediator 的引用,以便与中介者进行交互。 通过中介者对象,同事对象可以与其他同事对象进行通信。
  4. ChatUser (具体同事类):

    • ChatUser 继承自 User 类,实现了 send()receive() 方法。 具体同事类实现了抽象同事类,并负责实现具体的业务逻辑。
    • send() 方法调用中介者的 sendMessage() 方法来发送消息。 通过中介者发送消息,降低了同事对象之间的耦合度。
    • receive() 方法用于接收消息并打印到控制台。 接收到消息后,将消息内容打印到控制台。
  5. MediatorPatternDemo (客户端):

    • 客户端代码创建 ChatRoom 对象 (中介者)。 创建中介者对象,用于协调用户之间的交互。
    • 客户端代码创建多个 ChatUser 对象,并将它们添加到聊天室中。 创建多个用户对象,并将它们添加到聊天室中。
    • 客户端代码调用 ChatUsersend() 方法来发送消息,消息通过中介者传递给其他用户。 用户通过调用send方法发送消息,消息会通过中介者传递给其他用户。

6. 总结

中介者模式是一种行为型设计模式,它通过引入一个中介者对象,将对象之间的交互行为集中管理,从而降低对象之间的耦合度,简化系统结构。 中介者模式特别适用于对象之间存在复杂的交互关系,且这些交互关系可以被抽象和集中化的场景。