当前位置: 首页 > news >正文

设计模式十八:中介者模式(Mediator Pattern)

在中介者模式中,多个对象之间不再直接相互通信,而是通过一个中介者对象进行通信。这可以减少对象之间的依赖关系,使系统更加模块化。中介者模式适用于当对象之间的通信逻辑变得复杂,导致代码难以维护和理解时。

中介者模式使用场景

  1. 对象之间的交互复杂度高
    当系统中的对象之间需要频繁地相互通信,导致交互逻辑复杂且难以维护时,可以考虑使用中介者模式来将这些复杂的交互逻辑集中管理。
  2. 对象之间的耦合度高
    如果对象之间的耦合度过高,修改一个对象可能会影响到其他对象,使得系统难以扩展和维护。中介者模式可以降低对象之间的直接依赖关系,从而减少耦合度。
  3. 分布式系统
    在分布式系统中,不同节点之间需要通信和协调。使用中介者模式可以在不同节点之间引入一个中介者,负责协调节点之间的通信,从而简化分布式系统的设计和管理。
  4. 图形界面应用
    在图形界面应用中,各个界面元素之间需要相互响应和协调,例如按钮点击触发其他界面元素的更新。中介者模式可以用来管理界面元素之间的交互,避免它们之间的紧密耦合。
  5. 多人协作系统
    在多人协作系统中,不同用户或角色之间需要相互协调和通信。中介者模式可以用于管理不同用户或角色之间的交互,确保协作流程的顺畅进行。
  6. 消息传递系统
    当系统中需要实现消息传递和通信时,可以使用中介者模式来管理消息的发送和接收,确保消息传递的可靠性和一致性。
    中介者模式虽然有诸多优点,但在一些情况下可能会引入一个单点故障,即中介者本身出现问题可能会影响整个系统的功能。因此,在使用中介者模式时,需要谨慎权衡和设计中介者的职责和功能,确保模式的有效性和稳定性。

中介者模式的主要角色

中介者模式的核心思想是将对象之间的交互从彼此之间解耦,通过引入中介者来管理交互,从而使系统更加灵活、可维护和可扩展。这种模式的使用可以使得系统的交互逻辑变得更加清晰,并减少对象之间复杂的直接关联。

  1. 中介者(Mediator)
    中介者是该模式的核心,负责定义对象之间的通信接口和协调规则。它持有对所有相关同事类对象的引用,并根据业务逻辑协调它们之间的交互。中介者通常封装了复杂的交互逻辑,使对象之间的通信更加简单和集中。
  2. 同事类(Colleague)
    同事类是需要相互通信的对象,每个同事类都知道中介者对象并通过中介者来与其他同事类进行通信。同事类之间不直接通信,而是通过中介者进行交互,从而降低了对象之间的耦合度。
    在一些实现中,同事类可以分为两类:
    具体同事类(Concrete Colleague)
    具体同事类实现了同事类的接口,通过中介者与其他具体同事类进行通信。每个具体同事类通常只关心自己的业务逻辑,而将交互逻辑委托给中介者处理。
    抽象同事类(Abstract Colleague)
    抽象同事类定义了同事类的接口,通常包括一个指向中介者的引用。具体同事类通过继承抽象同事类来实现通信功能。

java代码实例

创建一个聊天室的场景,其中用户可以通过中介者给其它所有用户发送消息,或者接受其它用户发送的消息
中介者接口

//终结者接口
public interface ChatMediator {//添加用户void addUser(User user);void sendMessage(String message, User user);}

中介者实现类

public class ChatMediatorImpl implements ChatMediator{//用户组private  List<User> users;//创建中介者的时候,初始化用户组public  ChatMediatorImpl(){this.users=new ArrayList<>();}@Overridepublic void addUser(User user) {this.users.add(user);}@Overridepublic void sendMessage(String message, User user) {for (User u : users) {if (u != user) {u.receiveMessage(message);}}}}

抽象用户

public interface User {//发送信息给中介void sendMassageToMe(String message);//接受消息void receiveMessage(String message);}

具体用户

public class ConcreteUser implements User{private ChatMediator  chatMediator;private String name;public ConcreteUser(String name,ChatMediator  chatMediator){this.chatMediator=chatMediator;this.name= name;chatMediator.addUser(this);}@Overridepublic void sendMassageToMe(String message) {System.out.println(name + " sends message: " + message);chatMediator.sendMessage(message,this);}@Overridepublic void receiveMessage(String message) {System.out.println(name+" receive a Message!"+message);}
}

客户端

public static void main(String[] args) {//初始化的时候就创建一个User组ChatMediator chatMediator = new ChatMediatorImpl();//创建三个用户,并且吧用户添加到了用户组中User user1 = new ConcreteUser("User 1", chatMediator);User user2 = new ConcreteUser("User 2", chatMediator);User user3 = new ConcreteUser("User 3", chatMediator);//用户发送消息user1.sendMassageToMe("Hello, everyone!");user2.sendMassageToMe("Hi there!");
}

运行结果

User 1 sends message: Hello, everyone!
User 2receive a Message!Hello, everyone!
User 3receive a Message!Hello, everyone!
User 2 sends message: Hi there!
User 1receive a Message!Hi there!
User 3receive a Message!Hi there!

中介者模式的优缺点

中介者模式在复杂的对象交互场景中可以提供许多优点,但在简单场景下可能会显得过于繁琐。使用中介者模式时,需要根据具体情况权衡其优缺点,确保模式的使用能够带来实际的设计和维护好处。
优点:

  1. 降低耦合度:
    中介者模式可以减少对象之间的直接依赖关系,从而降低系统的耦合度。各个对象只需要和中介者进行通信,而不需要了解其他对象的详细信息。
  2. 简化对象交互:
    中介者模式将复杂的交互逻辑集中在中介者中,使得对象之间的交互变得简单和集中。这有助于提高代码的可读性和维护性。
  3. 集中管理:
    中介者模式可以集中管理对象之间的交互逻辑,使系统的逻辑更加清晰。通过将交互逻辑封装在中介者中,可以更容易地进行修改和扩展。
  4. 易于扩展:
    当需要添加新的对象或修改交互规则时,只需修改中介者类,而不需要修改其他对象的代码。这使得系统更加容易扩展和维护。
  5. 促进重用:
    中介者模式可以将交互逻辑从各个对象中抽取出来,使得这些逻辑可以被多个对象共享和重用。

缺点:

  1. 中介者复杂:
    在某些情况下,中介者可能会变得复杂,尤其是当系统中有大量对象和复杂的交互逻辑时。这可能导致中介者本身难以维护。
  2. 单点故障:
    中介者模式引入了一个中心化的中介者对象,如果这个中介者出现问题,可能会影响整个系统的功能。这可能会增加系统的脆弱性。
  3. 通信间接性:
    中介者模式使得对象之间的通信变为间接的,可能会导致一些通信变得复杂,降低了部分直接性。
  4. 不适用简单场景:
    在对象之间的交互相对简单的情况下,使用中介者模式可能会引入不必要的复杂性,增加代码的复杂度。

相关文章:

设计模式十八:中介者模式(Mediator Pattern)

在中介者模式中&#xff0c;多个对象之间不再直接相互通信&#xff0c;而是通过一个中介者对象进行通信。这可以减少对象之间的依赖关系&#xff0c;使系统更加模块化。中介者模式适用于当对象之间的通信逻辑变得复杂&#xff0c;导致代码难以维护和理解时。 中介者模式使用场…...

神经网络基础-神经网络补充概念-12-向量化逻辑回归的梯度输出

代码实现 import numpy as npdef sigmoid(z):return 1 / (1 np.exp(-z))def compute_loss(X, y, theta):m len(y)h sigmoid(X.dot(theta))loss (-1/m) * np.sum(y * np.log(h) (1 - y) * np.log(1 - h))return lossdef compute_gradient(X, y, theta):m len(y)h sigmoi…...

2023-08-16力扣每日一题

链接&#xff1a; 2682. 找出转圈游戏输家 题意&#xff1a; 环形1到n&#xff0c;从1开始&#xff0c;每次移动 第i次*k &#xff0c;当移动到出现过的序号时停下&#xff0c; 求没移动到的数字 解&#xff1a; 简单模拟题&#xff0c;我也以为有数学做法&#xff0c;可…...

耗资170亿美元?三星电子在得克萨斯州建设新的半导体工厂

据报道&#xff0c;三星电子在得克萨斯州泰勒市建设的新的半导体工厂预计将于2024年下半年投入运营。这座工厂将成为三星电子在美国的第二座芯片代工厂&#xff0c;与位于得克萨斯州奥斯汀市的第一座工厂相距不远。 此次投资将耗资约170亿美元&#xff0c;显示了三星电子在半导…...

黑马项目一阶段面试58题 Web14题(一)

一、什么是AJAX 异步的JavaScript和XML。用来做前端和后端的异步请求的技术。 异步请求&#xff1a;只更新部分前端界面的请求&#xff0c;做到局部更新。 比如注册&#xff0c;提示用户名已存在而整个页面没有动 比如百度图片搜索美女&#xff0c;进度条越变越短&#xff…...

多线程与高并发--------线程池

线程池 一、什么是线程池 在开发中&#xff0c;为了提升效率的操作&#xff0c;我们需要将一些业务采用多线程的方式去执行。 比如有一个比较大的任务&#xff0c;可以将任务分成几块&#xff0c;分别交给几个线程去执行&#xff0c;最终做一个汇总就可以了。 比如做业务操…...

深度学习实战48-【未来的专家团队】基于AutoCompany模型的自动化企业概念设计与设想

大家好,我是微学AI,今天给大家介绍一下深度学习实战48-【未来的专家团队】基于AutoCompany模型的自动化企业概念设计与设想,文本将介绍AutoCompany模型的概念设计,涵盖了AI智能公司的各个角色,并结合了GPT-4接口来实现各个角色的功能,设置中央控制器,公司运作过程会生成…...

深入剖析:如何通过API优化云计算架构?快来看!

在当今数字化时代&#xff0c;云计算已经成为企业实现创新、提高效率和降低成本的核心策略之一。而在构建和管理云计算架构时&#xff0c;API&#xff08;应用程序编程接口&#xff09;的作用变得愈发重要。本文将深入探讨如何通过API优化云计算架构&#xff0c;实现更高效、灵…...

基于STM32设计的中药分装系统

一、设计需求 基于STM32设计的中药分装系统 【1】项目背景 中药文化是我国文化瑰宝之一,它具有疗效好、副作用小的优点,而且相对于西药,全天然的中药还具有标本兼治的特点,不仅可以用来治病,更可以对患者身体进行调理,所以格外受到当今一直追求生活质量的人们的追捧&quo…...

消息队列学习笔记

消息队列基础 适合消息队列解决的问题 异步处理&#xff1a;处理完关键步骤后直接返回结果&#xff0c;后续放入队列慢慢处理流量控制&#xff1a; 使用消息队列隔离网关和后端服务&#xff0c;以达到流量控制和保护后端服务的目的。能根据下游的处理能力自动调节流量&#x…...

贝锐蒲公英:助力企业打造稳定高效的智能安防监控网络

随着技术的快速发展和物联网的普及&#xff0c;企业面临着许多安全威胁和风险&#xff0c;如盗窃、入侵、信息泄露等&#xff0c;企业需要建立安防监控系统来保护其资产、员工和业务运营的安全。 然而&#xff0c;企业在搭建安防监控系统的过程中&#xff0c;可能会面临一些难…...

SASS 学习笔记

SASS 学习笔记 总共会写两个练手项目&#xff0c;成品在 https://goldenaarcher.com/scss-study 可以看到&#xff0c;代码在 https://github.com/GoldenaArcher/scss-study。 什么是 SASS SASS 是 CSS 预处理&#xff0c;它提供了变量&#xff08;虽然现在 CSS 也提供了&am…...

Web菜鸟教程 - Springboot接入认证授权模块

网络安全的重要性不言而喻&#xff0c;如今早已不是以前随便弄个http请求就能爬到数据的时代&#xff0c;而作为一个架构师&#xff0c;网络安全必须在产品开发之初就考虑好。因为在产品开发的后期&#xff0c;一方面是客户增多&#xff0c;压力变大&#xff0c;可供利用的时间…...

【深入理解ES6】块级作用域绑定

1. var声明及变量提升机制 提升&#xff08;Hoisting&#xff09;机制&#xff1a;通过关键字var声明的变量&#xff0c;都会被当成在当前作用域顶部生命的变量。 function getValue(condition){if(condition){var value "blue";console.log(value);}else{// 此处…...

使用fake为数据库生成随机数据

参考https://cloud.tencent.com/developer/article/1663417 增加了自己的代码&#xff0c;使得只需要构建内容映射字典&#xff0c;然后根据字典就可以直接将数据插入到数据库中 from faker import Faker import pandas as pd from urllib import parse # from pymongo import…...

树结构转List

使用LinkedList效率更高 1、单个顶级节点 public static List<CmsStudentOutline> getTreeList(CmsStudentOutline root) {List<CmsStudentOutline> list new ArrayList<>();Queue<CmsStudentOutline> queue new LinkedList<>();if (root nu…...

Android复习(Android基础-四大组件)——Broadcast

1. 广播分类 广播的发送方式&#xff1a;标准广播、有序广播、粘性广播广播的类型&#xff1a;系统广播、本地广播 1.1 标准广播 完全异步&#xff0c;无序的广播发出后&#xff0c;所有的广播接收器几乎都会在同一时间收到消息。&#xff08;异步&#xff09;但是消息无法截…...

Ubuntu下mysql8开启远程连接

环境 mysql8ubuntu22.04 更改配置文件 vim /etc/mysql/mysql.conf.d/mysqld.conf找到 bind-address 127.0.0.1 mysqlx-bind-address 127.0.0.1 把这两行注释掉&#xff0c;保存退出即可 修改mysql配置 登录mysql创建一个远程连接账户,名字任意&#xff0c;密码任意,用户名…...

java对象和json类型转换

fastjson参考 参考&#xff1a;http://doc.yaojieyun.com/www.runoob.com/w3cnote/java-json-instro.html 参考&#xff1a; http://doc.yaojieyun.com/www.runoob.com/w3cnote/fastjson-intro.html 序列化&#xff1a;JSON.toJSONString(person)将Java 对象转换为 JSON 字符串…...

elasticsearch-head 插件

1、elastic 插件说明 **Head** 是第三方提供的一款很优秀的插件&#xff0c;集监控、查询、配置一体的web功能系统&#xff0c;可以在系统中进行创建、删除索引 、文档。以及查询、配置索引等功能&#xff0c;深受广大开发者的喜爱 **Kopf** 是另一个第三方提供的一款很优秀…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系&#xff0c;可直观判断线性相关、非线性相关或无相关关系&#xff0c;点的分布密…...