【重温设计模式】中介者模式及其Java示例

中介者模式的基本概念

在我们的日常生活中,有许多事情是需要通过一个"中介"来完成的,比如租房、买房、找工作等。在软件设计中,也有一种名为"中介者模式"的设计模式,它的作用和我们生活中的"中介"有着异曲同工之妙。

中介者模式,是一种行为设计模式,它定义了一个对象,这个对象可以封装一组对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。换句话说,如果你有一堆类,它们之间的关系复杂且混乱,那么你可以通过引入一个中介者类,来将这些关系集中管理,使得这些类之间的关系变得清晰有序。

举一个简单的例子,我们来看看Java的java.util.Timer类。这个类就是一个典型的中介者,它管理了一组TimerTask对象之间的调度和执行。每个TimerTask对象都不需要知道其他TimerTask的存在,它们只需要关注自己的任务,而具体的调度和执行则由Timer来负责。

java 复制代码
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实例

在了解了中介者模式的基本概念后,我们来看一个Java实例,以便更直观地理解其工作原理。这个实例是一个简单的聊天室程序,用户(Colleague)之间的消息交流通过聊天室(Mediator)进行。

在这个例子中,我们首先定义一个Mediator接口,它有一个方法sendMessage,用于发送消息。然后,我们创建一个ChatRoom类,实现Mediator接口。在ChatRoom类中,我们用一个HashMap来存储所有的用户,并在sendMessage方法中,通过用户的名字来找到对应的用户,然后发送消息。

java 复制代码
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的引用,这样,用户就可以通过中介者来发送消息。

java 复制代码
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);
    }
}

最后,我们创建一些用户,并添加到聊天室中。然后,用户就可以通过聊天室来发送消息了。

java 复制代码
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!");
    }
}

整个类图如下图:
uses implements creates creates User -String id -Mediator mediator +User(String id, Mediator mediator) +getId() +send(String message) +receive(String message) ChatRoom -HashMap<String, User> usersMap +sendMessage(String message, String userId) +addUser(User user) OneMoreClass +main(args) <<interface>> Mediator +sendMessage(String message, String userId)

在这个例子中,无论是用户之间的通信,还是用户和聊天室之间的通信,都通过中介者模式来进行,这样就降低了系统的耦合度。然而,这种模式也有其缺点,我们将在下一章节进行讨论。

中介者模式的优点与缺点

在我们前面的聊天室例子中,用户(Colleague)之间的消息交流通过聊天室(Mediator)进行,这样就避免了用户直接相互交流,降低了系统的耦合度。这就是中介者模式的一大优点。当系统中的对象之间的交互非常复杂,直接的交互会导致系统难以理解和维护时,中介者模式就能发挥其作用。通过引入一个中介者对象,将这些对象之间的交互都集中到中介者对象上,使得对象之间不再直接交互,从而降低了系统的耦合度,提高了系统的可维护性。

然而,中介者模式也不是没有缺点的。当系统中的对象交互非常复杂,中介者对象的职责就会非常大,它会变得复杂而庞大,难以维护。这也是我们在使用中介者模式时需要注意的一点。中介者模式提供了一种将对象之间的交互集中处理的方式,但是这种方式也有可能带来中介者对象的复杂性和难以维护的问题。因此,在使用中介者模式时,我们需要根据实际情况来选择是否使用,以及如何使用。

总结

正如我们在生活中的中介一样,程序设计中的中介者模式扮演着协调与调度的角色,将一系列复杂的交互关系简化,降低了系统的耦合度,提升了代码的可维护性。然而,正如人们对生活中的中介存在着褒贬不一的看法,中介者模式也并非完美无缺。当中介者的职责过大,它可能会变得复杂而庞大,难以维护。

那么,我们在设计和编程时,应如何看待和使用中介者模式呢?我认为,这需要我们具备一种审视问题和解决问题的平衡视角。中介者模式的引入,无疑可以帮助我们简化复杂的交互关系,但同时我们也不能忽视它可能带来的问题。因此,我们需要根据实际情况,权衡利弊,恰当地使用中介者模式。

相关推荐
m0_7482451717 分钟前
Web第一次作业
java
小码的头发丝、17 分钟前
Java进阶学习笔记|面向对象
java·笔记·学习
m0_5485147720 分钟前
前端Pako.js 压缩解压库 与 Java 的 zlib 压缩与解压 的互通实现
java·前端·javascript
坊钰1 小时前
【Java 数据结构】移除链表元素
java·开发语言·数据结构·学习·链表
chenziang11 小时前
leetcode hot100 LRU缓存
java·开发语言
会说法语的猪1 小时前
springboot实现图片上传、下载功能
java·spring boot·后端
码农老起1 小时前
IntelliJ IDEA 基本使用教程及Spring Boot项目搭建实战
java·ide·intellij-idea
m0_748239831 小时前
基于web的音乐网站(Java+SpringBoot+Mysql)
java·前端·spring boot
时雨h1 小时前
RuoYi-ue前端分离版部署流程
java·开发语言·前端