在我们的日常生活中,有许多事情是需要通过一个“中介”来完成的,比如租房、买房、找工作等。在软件设计中,也有一种名为“中介者模式”的设计模式,它的作用和我们生活中的“中介”有着异曲同工之妙。
中介者模式,是一种行为设计模式,它定义了一个对象,这个对象可以封装一组对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。换句话说,如果你有一堆类,它们之间的关系复杂且混乱,那么你可以通过引入一个中介者类,来将这些关系集中管理,使得这些类之间的关系变得清晰有序。
举一个简单的例子,我们来看看Java的java.util.Timer
类。这个类就是一个典型的中介者,它管理了一组TimerTask
对象之间的调度和执行。每个TimerTask
对象都不需要知道其他TimerTask
的存在,它们只需要关注自己的任务,而具体的调度和执行则由Timer
来负责。
public class OneMoreClass {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("Task executed.");
}
};
timer.schedule(task, 1000);
}
}
在上面的代码中,我们创建了一个Timer
对象和一个TimerTask
对象。TimerTask
对象只需要定义自己的任务(在这里是打印一条消息),而不需要关心何时执行这个任务,这个任务的调度和执行则由Timer
对象来负责。
在接下来的内容中,我们将通过一个更具体的例子,来详细介绍如何在实际的项目中使用中介者模式。
在了解了中介者模式的基本概念后,我们来看一个Java实例,以便更直观地理解其工作原理。这个实例是一个简单的聊天室程序,用户(Colleague)之间的消息交流通过聊天室(Mediator)进行。
在这个例子中,我们首先定义一个Mediator
接口,它有一个方法sendMessage
,用于发送消息。然后,我们创建一个ChatRoom
类,实现Mediator
接口。在ChatRoom
类中,我们用一个HashMap
来存储所有的用户,并在sendMessage
方法中,通过用户的名字来找到对应的用户,然后发送消息。
public interface Mediator {
void sendMessage(String message, String userId);
}
public class ChatRoom implements Mediator {
private HashMap<String, User> usersMap = new HashMap<>();
@Override
public void sendMessage(String message, String userId) {
User user = usersMap.get(userId);
if (user != null) {
user.receive(message);
}
}
public void addUser(User user) {
this.usersMap.put(user.getId(), user);
}
}
接下来,我们定义一个User
类,它有一个receive
方法,用于接收消息。在User
类中,我们还要保存一个对Mediator
的引用,这样,用户就可以通过中介者来发送消息。
public class User {
private String id;
private Mediator mediator;
public User(String id, Mediator mediator) {
this.id = id;
this.mediator = mediator;
}
public String getId() {
return id;
}
public void send(String message) {
System.out.println(this.id + " 发送消息: " + message);
mediator.sendMessage(message, this.id);
}
public void receive(String message) {
System.out.println(this.id + " 接收消息: " + message);
}
}
最后,我们创建一些用户,并添加到聊天室中。然后,用户就可以通过聊天室来发送消息了。
public class OneMoreClass {
public static void main(String[] args) {
Mediator chatRoom = new ChatRoom();
User user1 = new User("One", chatRoom);
User user2 = new User("More", chatRoom);
chatRoom.addUser(user1);
chatRoom.addUser(user2);
user1.send("Hello, More!");
user2.send("Hello, One!");
}
}
整个类图如下图:
在这个例子中,无论是用户之间的通信,还是用户和聊天室之间的通信,都通过中介者模式来进行,这样就降低了系统的耦合度。然而,这种模式也有其缺点,我们将在下一章节进行讨论。
在我们前面的聊天室例子中,用户(Colleague)之间的消息交流通过聊天室(Mediator)进行,这样就避免了用户直接相互交流,降低了系统的耦合度。这就是中介者模式的一大优点。当系统中的对象之间的交互非常复杂,直接的交互会导致系统难以理解和维护时,中介者模式就能发挥其作用。通过引入一个中介者对象,将这些对象之间的交互都集中到中介者对象上,使得对象之间不再直接交互,从而降低了系统的耦合度,提高了系统的可维护性。
然而,中介者模式也不是没有缺点的。当系统中的对象交互非常复杂,中介者对象的职责就会非常大,它会变得复杂而庞大,难以维护。这也是我们在使用中介者模式时需要注意的一点。中介者模式提供了一种将对象之间的交互集中处理的方式,但是这种方式也有可能带来中介者对象的复杂性和难以维护的问题。因此,在使用中介者模式时,我们需要根据实际情况来选择是否使用,以及如何使用。
正如我们在生活中的中介一样,程序设计中的中介者模式扮演着协调与调度的角色,将一系列复杂的交互关系简化,降低了系统的耦合度,提升了代码的可维护性。然而,正如人们对生活中的中介存在着褒贬不一的看法,中介者模式也并非完美无缺。当中介者的职责过大,它可能会变得复杂而庞大,难以维护。
那么,我们在设计和编程时,应如何看待和使用中介者模式呢?我认为,这需要我们具备一种审视问题和解决问题的平衡视角。中介者模式的引入,无疑可以帮助我们简化复杂的交互关系,但同时我们也不能忽视它可能带来的问题。因此,我们需要根据实际情况,权衡利弊,恰当地使用中介者模式。