• 「聊设计模式」之中介者模式(Mediator)


    在这里插入图片描述


    🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎持续关注&&收藏&&订阅!


    大家下午好,我是bug菌,今天我们继续聊设计模式

    前言

      在软件开发过程中,我们通常会遇到一个问题,那就是对象之间的耦合度过高,难以维护和扩展。而中介者模式则是为了解决这个问题而生的。

      本文将对中介者模式进行详细的介绍,并给出相应的实现代码和测试用例。

    摘要

      中介者模式是一种行为型设计模式,它主要用于将关系复杂的对象之间的通信进行解耦,让它们通过一个中介对象来进行通信。这样做可以降低对象之间的耦合度,使得系统更加灵活和可扩展。

    中介者模式

    概念

      中介者模式是一种行为设计模式,它通过提供一个中介对象来协调一组对象之间的交互。中介者对象封装了一些对象之间的通信方式,使得它们不需要直接相互引用,从而降低它们之间的依赖性和耦合度。中介者模式常用于复杂的系统中,例如GUI系统、企业应用程序等。在这些系统中,对象之间的关系非常复杂,因此使用中介者模式可以使得系统更易于维护和扩展。

    结构

    中介者模式的结构包括以下角色:

    1. 抽象中介者(Mediator):定义中介者接口,声明各种业务方法。

    2. 具体中介者(Concrete Mediator):实现抽象中介者接口,协调各同事对象的业务行为,负责与各个同事对象之间的通信和协调。

    3. 抽象同事类(Colleague):定义同事类接口,声明一些抽象方法,用于与中介者进行通信。

    4. 具体同事类(Concrete Colleague):实现抽象同事类接口,与其他同事对象通信时,需要通过中介者来协作。

      在中介者模式中,中介者角色扮演着协调者和调度者的角色,充当着各个同事类之间的桥梁和连接点,使得各个同事类之间不直接交互,而是通过中介者来进行通信和协调,从而降低了系统的耦合度,提高了系统的可维护性和扩展性。

    如下是中介者模式的UML类图:

    在这里插入图片描述

      其中,Mediator是中介者接口,它定义了中介者对象所具有的方法;ConcreteMediator是具体的中介者对象,它实现了中介者接口;Colleague是抽象同事类,它定义了同事类所具有的方法和属性;ConcreteColleague是具体的同事类,它实现了抽象同事类中定义的方法和属性。

    优缺点

    优点

    中介者模式的优点如下:

    1. 减少类之间的依赖性,提高代码的可维护性和可扩展性;
    2. 中介者将系统内部的交互逻辑集中在一起,降低了系统中对象之间的耦合度;
    3. 可以简化对象之间的相互通信,使其更加灵活、易于扩展和维护;
    4. 可以将系统中的复杂性分解到中介者中,使得各个模块职责更加分明,易于管理和维护。

    缺点

    中介者模式的缺点如下:

    1. 中介者模式的实现需要在系统内部引入一个中介者对象,增加了系统的复杂性;
    2. 中介者对象可能会变得过于复杂,难以维护和拓展;
    3. 中介者模式会导致系统中对象之间的通信变得间接,降低了通信效率;
    4. 中介者对象可能会成为系统的瓶颈,影响系统的性能。

    应用场景

    中介者模式适用于以下场景:

    1. 当一组对象之间的通信复杂且相互关联时,可以使用中介者模式来减少耦合度。

    2. 当一个对象的行为取决于许多其他对象的状态时,可以使用中介者模式来统一管理这些对象的状态。

    3. 当需要观察一个对象并且需要与该对象的许多其他对象交互时,可以使用中介者模式来管理这些交互。

    4. 当一个系统中的对象之间需要经常互相通信,但是直接通信会导致复杂度增加时,可以使用中介者模式来简化通信过程。

    5. 当需要对一个对象进行修改时,可以使用中介者模式来隔离出需要修改的代码部分,从而减少风险和复杂度。

    模式实现

      下面是一个简单的中介者模式的示例,它实现了一个聊天室的功能。聊天室中有多个用户,他们之间可以相互发送消息。

    Mediator接口

    package com.example.javaDesignPattern.mediator;
    
    /**
     * @Author bug菌
     * @Date 2023-09-19 22:47
     */
    public interface Mediator {
        void sendMessage(String message, User user);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ConcreteMediator

    package com.example.javaDesignPattern.mediator;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @Author bug菌
     * @Date 2023-09-19 22:47
     */
    public class ConcreteMediator implements Mediator {
    
        // 所有的用户
        private final Map<String, User> userMap;
    
        public ConcreteMediator() {
            this.userMap = new HashMap<>();
        }
    
        /**
         * 注册用户
         * @param user 待注册用户
         */
        public void registerUser(User user) {
            String userId = user.getUserId();
            if (!userMap.containsKey(userId)) {
                userMap.put(userId, user);
                user.setMediator(this);
            }
        }
    
        /**
         * 发送消息给指定用户
         * @param message 消息内容
         * @param user 接收用户
         */
        @Override
        public void sendMessage(String message, Colleague user) {
            String userId = user.getUserId();
            if (userMap.containsKey(userId)) {
                user.receiveMessage(message);
            } else {
                System.out.println("用户不存在");
            }
        }
    }
    
    
    • 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

    Colleague抽象类

    package com.example.javaDesignPattern.mediator;
    
    /**
     * @Author bug菌
     * @Date 2023-09-19 22:47
     */
    public abstract class Colleague {
    
        private final String userId;
        private Mediator mediator;
    
        public Colleague(String userId) {
            this.userId = userId;
        }
    
        public String getUserId() {
            return userId;
        }
    
        public Mediator getMediator() {
            return mediator;
        }
    
        public void setMediator(Mediator mediator) {
            this.mediator = mediator;
        }
    
        public void sendMessage(String message) {
            mediator.sendMessage(message, this);
        }
    
        public abstract void receiveMessage(String message);
    }
    
    
    • 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

    ConcreteColleague

    package com.example.javaDesignPattern.mediator;
    
    /**
     * @Author bug菌
     * @Date 2023-09-19 22:48
     */
    public class User extends Colleague {
    
        public User(String userId) {
            super(userId);
        }
    
        @Override
        public void receiveMessage(String message) {
            System.out.println("用户" + getUserId() + "收到消息:" + message);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    测试用例

    package com.example.javaDesignPattern.mediator;
    
    /**
     * @Author bug菌
     * @Date 2023-09-19 22:48
     */
    public class MediatorTest {
    
        public static void main(String[] args) {
            // 创建中介者
            ConcreteMediator mediator = new ConcreteMediator();
    
            // 创建用户
            User user1 = new User("张三");
            User user2 = new User("李四");
            User user3 = new User("王五");
    
            // 注册用户到中介者
            mediator.registerUser(user1);
            mediator.registerUser(user2);
            mediator.registerUser(user3);
    
            // 用户发送消息
            user1.sendMessage("大家好,我是张三");
            user2.sendMessage("你们好,我是李四");
            user3.sendMessage("大家好,我是王五");
        }
    }
    
    • 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

    测试结果如下:

    在这里插入图片描述

    测试用例代码解析

    如上代码用例演示了中介者模式,其中:

    • 存在一个中介者类 ConcreteMediator,其内部维护了一个用户列表,提供了一个注册用户和接收消息的方法;
    • 存在一个用户类User,其内部维护了自己的名字和一个发送消息的方法;
    • 在 main 方法中,首先创建了中介者和三个用户,并将用户注册到中介者中;
    • 然后分别通过用户对象的 sendMessage 方法发送消息,实际上是调用中介者对象的 receiveMessage 方法,中介者再将消息广播给其它注册过的用户。

      通过使用中介者模式,用户类和中介者类解耦,用户只需要知道发送消息即可,而无需关心具体发送给了哪些用户。而中介者类则负责实现消息的广播,也无需知道具体是哪些用户发送了消息。这样就提高了系统的灵活性和可维护性。

    附录源码

      如上涉及代码均已上传同步在GitHub,提供给同学们参考性学习。

    总结

      中介者模式是一种能够有效解耦对象之间关系的设计模式。通过一个中介者对象来协调和处理它们之间的通信,从而降低对象之间的耦合度,提高系统的灵活性和可扩展性。

      在实现中介者模式时,需要定义好中介者接口和抽象同事类,然后再实现具体的中介者对象和同事类。在中介者对象中,需要维护一个同事类的列表,用于处理同事类之间的通信。

      在使用中介者模式时,需要注意中介者对象的复杂性,如果中介者对象过于复杂,会导致整个系统的性能降低,不利于系统的维护和扩展。

      总之,中介者模式在实际开发中有着广泛的应用,我们需要根据具体的需求来选择合适的设计模式,从而设计出高效、可维护、可扩展的软件系统。

    ☀️建议/推荐你


      如果想系统性的全面学习设计模式,建议小伙伴们直接毫无顾忌的关注这个专栏《聊设计模式》,无论你是想提升自己的编程技术,还是渴望更好地理解代码背后的设计思想,本专栏都会为你提供实用的知识和启发,帮助你更好地解决日常开发中的挑战,将代码变得更加优雅、灵活和可维护!

      最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

      同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

    📣关于我

      我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。


  • 相关阅读:
    聚合查询、联合查询【mysql数据库】
    Keil C51与Keil MDK的兼容安装
    使用docker运行应用程序
    AI界的宝藏图:揭秘最牛AI网站,轻松成为智能科技达人!
    Web框架开发-web框架
    C/C++数据结构——队列
    linux安装Android打包环境
    Windows11微软edge下载文件时无法下载-没有权限
    Linux系统之编译安装python3
    18.9k star!一个高性能的嵌入式分析型数据库,主要用于数据分析和数据处理任务
  • 原文地址:https://blog.csdn.net/weixin_43970743/article/details/133038427