java设计模式学习之【中介者模式】

文章目录

  • 引言
  • 中介者模式简介
    • 定义与用途
    • 实现方式
  • 使用场景
  • 优势与劣势
  • 在Spring框架中的应用
  • 聊天室示例
  • 代码地址

引言

想象一下一座忙碌的机场,各种飞机需要起飞、降落,而不同的飞行活动之间必须互不干扰。如果没有一个统一的控制系统,这将是一场混乱。空中交通控制塔(ATC)作为中介者,协调各个飞机的活动,确保一切有序进行。在软件开发中,我们也经常遇到多个对象需要相互通信和协调的情况,中介者模式为这种复杂的通信和控制提供了一种简单明了的解决方案。

中介者模式简介

定义与用途

中介者模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个第三方对象(中介者)来管理一组对象之间的复杂交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,并且可以独立地改变它们之间的交互。

实现方式

实现中介者模式通常涉及以下几个关键组件:

  • 中介者接口(Mediator):定义了同事对象到中介者对象的接口,用于各同事对象通知中介者。
  • 具体中介者(Concrete Mediator):实现中介者接口,并协调各同事对象之间的交互。
  • 同事类(Colleague):所有同事类的接口。每个同事只知道自己的行为,而不了解其他同事的情况,但它们知道中介者。

使用场景

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

  • 当一组对象之间的通信方式复杂混乱时。
  • 当需要一个对象来管理这些交互,并使其互不依赖时。
  • 当你想定制一个分布在多个类中的行为,而又不想生成太多的子类时。

例如:

  • 聊天室:聊天室作为中介者,协调多个用户(同事)之间的消息传递。
  • GUI中的窗口系统:窗口或对话框作为中介者,协调各种GUI组件(按钮、文本框、列表等)之间的交互。
  • 航班调度系统:调度中心作为中介者,管理多个航班的起降和空中路径。

优势与劣势

  • 优势
    减少了类之间的依赖,降低了耦合度。
    将一对多的依赖转化为一对一的依赖,提高了系统的可维护性。
    中心化的控制交互逻辑,使其易于理解和修改。
  • 劣势
    中介者本身可能变得过于复杂,集中了过多的逻辑。

在Spring框架中的应用

在Spring框架中,虽然不常直接提到中介者模式,但是许多Spring的核心概念和组件实际上体现了中介者模式的精神。中介者模式的核心思想是通过一个中介对象来封装一系列对象之间的交互,使对象之间不需要显式地相互引用,从而使其耦合松散,而Spring框架恰恰提倡控制反转和依赖注入来实现松耦合。

以下是Spring框架下体现中介者模式思想的几个方面:

1. Spring容器作为中介者
在Spring中,容器(如ApplicationContext)充当中介者的角色,管理应用对象(Bean)的整个生命周期。容器负责创建Bean、注入依赖、配置Bean以及管理它们的生命周期。Bean之间不需要知道对方的存在,它们只通过配置文件或注解声明依赖,由Spring容器来负责具体的依赖注入工作。

2. Spring MVC中的DispatcherServlet
在Spring MVC框架中,DispatcherServlet充当中介者的角色,负责协调各种Controller、Service、和View之间的交互。它接收请求,委托给适当的处理器,然后再将模型数据传递给视图进行渲染。在这个过程中,DispatcherServlet确保各个组件相互之间的解耦和协调。

3. 事件发布和监听
Spring的事件发布-监听机制也是中介者模式的一个体现。在这种机制中,应用可以发布各种事件,而监听器可以监听这些事件。Spring的ApplicationEventPublisher充当中介者,管理事件的发布和监听器的通知。这种方式实现了事件发布者和监听者之间的松耦合。

4. JdbcTemplate和TransactionTemplate
Spring提供了一系列的模板,比如JdbcTemplate和TransactionTemplate,它们封装了对JDBC操作和事务管理的常见模式。这些模板类充当中介者的角色,管理数据库连接、语句的执行以及事务的边界,用户只需要提供具体的SQL和代码逻辑。

尽管这些组件和机制不是传统意义上的中介者模式,但它们体现了中介者模式背后的核心原则:封装对象之间的交互,提供一个统一的接口来协调各个组件或服务的行为。通过这种方式,Spring框架显著降低了组件之间的耦合度,并提高了整体的灵活性和可维护性。

聊天室示例

在这里插入图片描述
步骤 1:创建中介者类

import java.util.Date;

public class ChatRoom {
   public static void showMessage(User user, String message){
      System.out.println(new Date().toString() + " [" + user.getName() + "] : " + message);
   }
}

ChatRoom 充当中介者角色,提供一个静态方法 showMessage 来展示用户的消息。这个方法打印了消息的时间、发送者和内容。

步骤 2:创建用户类

public class User {
   private String name;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

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

   public void sendMessage(String message){
      ChatRoom.showMessage(this, message);
   }
}

User 类代表聊天室的用户。每个用户有一个名字,并且可以通过 sendMessage 方法来发送消息。当用户发送消息时,它实际上是调用了中介者 ChatRoom 的 showMessage 方法。

步骤 3:展示用户间的通信

public class MediatorPatternDemo {
   public static void main(String[] args) {
      User robert = new User("Robert");
      User john = new User("John");

      robert.sendMessage("Hi! John!");
      john.sendMessage("Hello! Robert!");
   }
}

在这里插入图片描述

在这个演示类中,我们创建了两个用户 Robert 和 John。然后我们让这两个用户相互发送消息。每当用户发送消息时,实际上是通过 ChatRoom(作为中介者)来显示消息的。

这个示例演示了中介者模式如何在软件设计中用于简化多个对象之间的通信。通过将对象之间的通信封装到一个中介者对象中,可以降低对象之间的直接交互,减少系统的复杂性,提高可扩展性和可维护性。

代码地址

23种设计模式相关代码后续会逐步提交到github上,方便学习,欢迎指点:
代码地址
https://github.com/RuofeiSun/lf-23Pattern

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/274761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计模式(4)--对象行为(7)--观察者

1. 意图 定义对象间的一种一对多的依赖关系, 当一个对象的状态改变时,所有依赖于它的对象都得到通知并被自动更新。 2. 四种角色 抽象目标(Subject)、具体目标(Concrete Subject)、抽象观察者(Observer)、 具体观察者(Concrete Observer) 3. 优点 3.1 …

ASUS华硕ROG幻16笔记本电脑2023款GU604VI VZ VY原装出厂Windows11系统22H2

华硕玩家国度幻16笔记本原厂W11系统,适用型号:GU604VI、GU604VZ、GU604VY 链接:https://pan.baidu.com/s/166x6FNUFEpA3Qbzeory3Hg?pwdlwau 提取码:lwau 系统自带所有驱动、出厂主题壁纸、Office办公软件、MyASUS华硕电脑管…

C++实现令牌桶过滤算法

什么是令牌桶算法 令牌桶算法通过限制令牌桶的固定容量,实现对资源以及流量的延迟控制。请求者需先获取令牌,方可执行动作。若令牌桶内具有足够令牌便可通过消耗相等数量放过请求;而若令牌不足,则会拒绝请求。 该算法具备平滑的…

uniapp实现前端银行卡隐藏中间的数字,及隐藏姓名后两位

Vue 实现前端银行卡隐藏中间的数字 主要应用了 filters过滤器 来实现效果 实现效果&#xff0c;如图&#xff1a; <template><div><div style"background-color: #f4f4f4;margin:50px 0 0 460px;width:900px;height:300px;"><p>原来&#…

【IoT网络层】STM32 + ESP8266 +MQTT + 阿里云物联网平台 |开源,附资料|

目标&#xff1a;实现STM32连接阿里云物联网平台发送数据同时接收数据&#xff0c;IOT studio界面显示数据。具体来说&#xff1a;使用ESP8266 ESP-01来连接网络&#xff0c;获取设备数据发送到阿里云物联网平台并显示且oled显示屏当前的设备数据&#xff0c;通过IOT studio界面…

是德科技E9304A功率传感器

是德科技E9304A二极管功率传感器测量频率范围为9 kHz至6 GHz的平均功率&#xff0c;功率范围为-60至20 dBm。该传感器非常适合甚低频(VLF)功率测量。E系列E9304A功率传感器有两个独立的测量路径&#xff0c;设计用于EPM系列功率计。功率计自动选择合适的功率电平路径。为了避免…

腾讯云轻量应用服务器购买流程、搭建网站全流程超详细

腾讯云轻量应用服务器开箱即用、运维简单的轻量级云服务器&#xff0c;CPU内存带宽配置高并且价格特别便宜&#xff0c;大带宽&#xff0c;但是限制月流量。轻量2核2G3M带宽62元一年、2核2G4M优惠价118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;756元3年、…

Havenask 分布式索引构建服务 --Build Service

Havenask 是阿里巴巴智能引擎事业部自研的开源高性能搜索引擎&#xff0c;深度支持了包括淘宝、天猫、菜鸟、高德、饿了么在内几乎整个阿里的搜索业务。本文针对性介绍了 Havenask 分布式索引构建服务——Build Service&#xff0c;主打稳定、快速、易管理&#xff0c;是在线系…

环形链表、环形链表 II、有效的括号​​​​​​​(leetcode)

目录 一、环形链表 方法&#xff08;快慢指针&#xff09;&#xff1a; 二、环形链表 II 三、有效的括号 一、环形链表 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链…

展现无限创意的Photoshop 2023 Mac/win中文版:打造您的独特艺术之旅

无论您是摄影师、设计师还是艺术家&#xff0c;Photoshop 2023&#xff08;ps 2023&#xff09;都是您不可或缺的创意工具。最新升级的Photoshop 2023带来了更多令人兴奋的功能和改进&#xff0c;让您能够以前所未有的方式展现无限创意。 首先&#xff0c;Photoshop 2023拥有强…

vue项目表单使用正则过滤ip、手机号

import useFormValidate from /hooks/useFormValidatesetup(props, { emit }) {const { validateName, validateIPAndPort } useFormValidate()const state reactive({workFaceInfo: props.info?.id ? props.info : {},sysTypeData: props.sysType,formRules: {name: [{req…

Java - 获取 Jar 包内的 pom.xml 文件

目录 一.引言 二.通过 jar 命令 ◆ 查看 Jar 包内文件 ◆ 导出 Pom.xml ◆ 导出 Jar 包内文件 三.通过 unzip 命令 ◆ 导出 Jar 包内文件 四.总结 一.引言 引用其他同学的 Jar 包时&#xff0c;需要获取其对应 jar 包内的 pom.xml 文件检查版本依赖关系&#xff0c;下…

[JS设计模式] Module Pattern

随着应用程序和代码库的增长&#xff0c;保持代码的可维护性和模块化变得越来越重要。模块模式允许将代码分成更小的、可重用的部分。 除了能够将代码分割成更小的可重用部分之外&#xff0c;模块还允许将文件中的某些值保留为私有。默认情况下&#xff0c;模块内的声明范围(封…

rabbitmq使用总结

1、进入rabbitmq的sbin目录&#xff0c;进入CMD 2、输入./rabbitmq-plugins enable rabbitmq_management启用管理服务。 3、输入./rabbitmqctl start_app启动服务。 查看是否启动成功 1、浏览器访问http://localhost:15672/ 下载erlang 地址如下&#xff1a; http://erla…

【PTA】L1-32 Left-pad (C++)

题目链接&#xff1a;L1-032 Left-pad 题目要求&#xff1a; 根据新浪微博上的消息&#xff0c;有一位开发者不满NPM&#xff08;Node Package Manager&#xff09;的做法&#xff0c;收回了自己的开源代码&#xff0c;其中包括一个叫left-pad的模块&#xff0c;就是这个模块…

MyBatis分页机制深度解析

前言 在企业项目的数据库操作中&#xff0c;分页查询是一个常见需求&#xff0c;尤其当数据量庞大时。MyBatis 作为 我们Java 开发者的持久层框架&#xff0c;为分页提供了灵活的支持。 本篇文章我们将深入探讨 MyBatis 的分页机制&#xff0c;使我们在实际开发项目中运用自如…

<JavaEE> TCP 的通信机制(三) -- 滑动窗口

目录 TCP的通信机制的核心特性 四、滑动窗口 1&#xff09;什么是滑动窗口&#xff1f; 2&#xff09;滑动窗口的作用是什么&#xff1f; 3&#xff09;批量传输出现丢包如何处理&#xff1f; 1> 接收端ACK丢包 2> 发送端数据包丢包 4&#xff09;适用性 TCP的通…

账号租号平台PHP源码,支持单独租用或合租使用

源码简介 租号平台源码&#xff0c;采用常见的租号模式。 平台的主要功能如下&#xff1a; 支持单独租用或采用合租模式&#xff1b; 采用易支付通用接口进行支付&#xff1b; 添加邀请返利功能&#xff0c;以便站长更好地推广&#xff1b; 提供用户提现功能&#xff1b;…

关于“Python”的核心知识点整理大全47

目录 16.1.10 错误检查 highs_lows.py highs_lows.py 16.2 制作世界人口地图&#xff1a;JSON 格式 16.2.1 下载世界人口数据 16.2.2 提取相关的数据 population_data.json world_population.py 16.2.3 将字符串转换为数字值 world_population.py 2world_population…

UWA社区年度大盘点

弹指间&#xff0c;2023年已接近尾声&#xff0c;这一年UWA社区为游戏行业开发者和期望步入游戏圈的学子们提供了多类型的社区服务&#xff0c;包括技术博客、问答、开源库、学堂、训练营、技术沙龙等。让我们一同回顾这一年来UWA的脚步&#xff0c;希望未来的每一步也都能有大…