程序员必知!中介者模式的实战应用与案例分析

程序员必知!中介者模式的实战应用与案例分析 - 程序员古德

中介者模式通过引入中介类降低对象间耦合度,在电商平台中,卖家、买家、物流公司和支付平台原本需复杂交互,在引入“交易中介”类后,各角色只需与中介交互,由中介协调各方操作,从而简化了交互流程,降低了类间依赖,使系统更灵活可维护。

定义

程序员必知!中介者模式的实战应用与案例分析 - 程序员古德

中介者模式主要用于减少类之间的耦合,它用一个中介类来封装一系列对象间的交互,使这些对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

举一个业务中的例子来说明,假设有一个电商平台,其中有卖家、买家、物流公司和支付平台四个角色,在没有中介者的情况下,这四个角色之间可能需要进行复杂的交互,比如卖家要直接联系物流公司发货,买家要直接联系支付平台进行支付等,这样的设计会导致类之间的耦合度很高,一旦某个角色发生变化,可能会影响到其他角色。

而引入中介者模式后,可以设计一个电商平台的“交易中介”类,这个类中介了卖家、买家、物流公司和支付平台之间的所有交互,卖家只需要将商品信息和买家信息提交给交易中介,交易中介会负责联系物流公司进行发货,并通知买家进行支付,买家支付完成后,交易中介会通知卖家和物流公司更新订单状态,这样,卖家、买家、物流公司和支付平台之间的耦合度就大大降低了,每个角色只需要和交易中介进行交互,而不需要直接和其他角色进行交互。

在这个场景中中,交易中介类就起到了中介者的作用,它将一系列对象间的交互封装起来,使这些对象之间的耦合度降低,提高了系统的灵活性和可维护性。

代码案例

程序员必知!中介者模式的实战应用与案例分析 - 程序员古德

反例

下面是一个未使用中介者模式的反例代码,假如,有一个聊天应用的简单模型,其中包括User(用户)和GroupChat(群聊)类,每个User对象都直接与其他User对象通信,如下代码演示:

public class User {  private String name;  public User(String name) {  this.name = name;  }  public String getName() {  return name;  }  public void sendMessage(User receiver, String message) {  System.out.println(name + " sends a message to " + receiver.getName() + ": " + message);  }  
}  public class GroupChat {  private List<User> users = new ArrayList<>();  public void addUser(User user) {  users.add(user);  }  public void notifyAllUsers(String message) {  for (User user : users) {  for (User otherUser : users) {  if (!user.equals(otherUser)) {  user.sendMessage(otherUser, message);}  }  }  }  
}  public class Client {  public static void main(String[] args) {  User alice = new User("Alice");  User bob = new User("Bob");  User charlie = new User("Charlie");  GroupChat chat = new GroupChat();  chat.addUser(alice);  chat.addUser(bob);  chat.addUser(charlie);  alice.sendMessage(bob, "Hi Bob, how are you?"); alice.sendMessage(charlie, "Hi Charlie, what's up?"); chat.notifyAllUsers("Everyone, there will be a maintenance tonight.");  }  
}

输出结果,如下:

Alice sends a message to Bob: Hi Bob, how are you?  
Alice sends a message to Charlie: Hi Charlie, what's up?  
Alice sends a message to Bob: Everyone, there will be a maintenance tonight.  
Alice sends a message to Charlie: Everyone, there will be a maintenance tonight.  
Bob sends a message to Alice: Everyone, there will be a maintenance tonight.  
Bob sends a message to Charlie: Everyone, there will be a maintenance tonight.  
Charlie sends a message to Alice: Everyone, there will be a maintenance tonight.  
Charlie sends a message to Bob: Everyone, there will be a maintenance tonight.

在这个反例中,User类直接持有对其他User对象的引用,并直接调用其方法,这导致了类之间的紧密耦合,因为User类需要知道如何与其他User对象通信,此外,GroupChat类虽然被设计出来,但并没有起到中介消息的作用,实际上,当notifyAllUsers方法被调用时,每个用户都会向其他每个用户发送消息,导致了重复的消息和不必要的复杂性。

正例

下面是一个使用中介者模式的正例代码,在这个例子中,有一个聊天应用的模型,包括User(用户)和ChatMediator(聊天中介)类,ChatMediator类作为中介者,封装了用户之间的通信逻辑,使得用户之间不需要直接相互引用,如下代码:

import java.util.*;  // User.java  
public class User {  private String name;  private ChatMediator chatMediator;  public User(String name, ChatMediator chatMediator) {  this.name = name;  this.chatMediator = chatMediator;  }  public String getName() {  return name;  }  // 用户通过中介者发送消息  public void sendMessage(String receiverName, String message) {  chatMediator.relayMessage(this, receiverName, message);  }  
}  // ChatMediator.java  
public class ChatMediator {  private Map<String, User> users = new HashMap<>();  public void registerUser(User user) {  users.put(user.getName(), user);  }  // 中介者负责将消息传递给指定的接收者  public void relayMessage(User sender, String receiverName, String message) {  User receiver = users.get(receiverName);  if (receiver != null) {  System.out.println(sender.getName() + " sends a message to " + receiver.getName() + ": " + message);  // 这里可以添加额外的逻辑,比如记录消息、通知其他服务等  } else {  System.out.println("Receiver " + receiverName + " is not online.");  }  }  
}  // 客户端代码  
public class Client {  public static void main(String[] args) {  // 创建中介者和用户  ChatMediator chatMediator = new ChatMediator();  User alice = new User("Alice", chatMediator);  User bob = new User("Bob", chatMediator);  // 用户注册到中介者  chatMediator.registerUser(alice);  chatMediator.registerUser(bob);  // Alice通过中介者发送消息给Bob  alice.sendMessage("Bob", "Hi Bob, how are you?");  // Bob通过中介者回复消息给Alice  bob.sendMessage("Alice", "I'm good, thanks!");  // 尝试发送消息给一个未注册的用户  alice.sendMessage("Charlie", "Hey Charlie, are you there?");  }  
}

输出结果:

Alice sends a message to Bob: Hi Bob, how are you?  
Bob sends a message to Alice: I'm good, thanks!  
Receiver Charlie is not online.

在这个正例中,User类不直接持有对其他User对象的引用,而是通过ChatMediator中介者来发送消息,ChatMediator维护了一个用户列表,并负责将消息从发送者传递给接收者,这样,User类之间的耦合度降低了,因为用户不需要知道如何与其他用户直接通信,他们只需要与中介者交互。此外,如果未来需要改变通信方式或添加额外的通信逻辑,只需要修改ChatMediator类即可,而不影响User类。

核心总结

程序员必知!中介者模式的实战应用与案例分析 - 程序员古德

中介者模式总结

通过引入中介者,使得各个组件之间不再直接相互依赖,减少了系统的复杂性,他将原本分散的交互逻辑集中管理,使得这些逻辑更加清晰和易于维护,由于组件间的通信都通过中介者进行,因此添加新组件或修改现有组件的交互方式变得更加容易。但随着系统的扩展,它可能需要处理越来越多的交互逻辑,导致其代码变得庞大且难以维护,为了实现中介者模式,有时可能需要创建额外的抽象类和接口,这可能会增加系统的复杂性和理解难度。

在确实需要降低组件间耦合度的情况下使用中介者模式,避免过度设计,可以考虑与其他设计模式(如观察者模式)结合使用,以实现更灵活和强大的功能。

和其它模式对比

中介者模式和装饰者模式两者的区别:

中介者模式主要用于降低多个对象之间的耦合度,通过引入一个中介者对象,其它所有相关对象都通过该中介者对象进行通信,而不是直接相互引用,当中介者模式中的某一个对象发生改变时,只需要通知中介者对象,由中介者对象负责与其他对象的交互,这样可以简化对象之间的交互,降低系统的复杂性。

装饰者模式则侧重于在不改变对象自身的基础上,动态地给对象添加新的功能或方法,装饰者模式通过创建一个装饰类,将原始类作为成员变量进行包装,并在装饰类中提供与原始类相同的方法,这些方法可以在调用原始类方法之前或之后执行一些额外的操作,这样可以实现对原始类功能的动态扩展,而无需修改原始类的代码。

总结,中介者模式主要用于解决对象之间的紧耦合问题,通过引入中介者来协调对象之间的交互;而装饰者模式则主要用于在不改变原始类的基础上,动态地给对象添加新的功能或方法。

关注我,每天学习互联网编程技术 - 程序员古德

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

APP加固技术及其应用

文章目录 引言 APP加固的概念 APP加固的方案 APP加固在实际开发中的应用 总结 引言 在移动应用开发过程中&#xff0c;APP加固技术起到了非常重要的作用。APP加固是将apk文件进行混淆加密&#xff0c;以防止别人反编译获取我们的源码和资源文件。目前市场上主流的APP加固…

手写一个加盐加密算法(java实现)

目录 前言 什么是MD5&#xff1f;&#xff1f; 加盐算法 那别的人会不会跟你得到相同的UUID&#xff1f; 如何使用盐加密&#xff1f; 代码实现 前言 对于我们常见的登录的时候需要用到的组件&#xff0c;加密是一个必不可少的东西&#xff0c;如果我们往数据库存放用户…

零售EDI:Petco EDI对接指南

Petco 始于1965年&#xff0c;是一家美国宠物零售商&#xff0c;提供各种宠物产品和服务以及某些类型的活体小动物。起初Petco只是一家邮购兽医用品公司&#xff0c;后发展为一家成熟的宠物食品和供应链的公司。Petco与其供应商之间是如何传输业务数据的呢&#xff1f; 通过EDI…

【docker笔记】DockerFile

DockerFile Docker镜像结构的分层 镜像不是一个单一的文件&#xff0c;而是有多层构成。 容器其实是在镜像的最上面加了一层读写层&#xff0c;在运行容器里做的任何文件改动&#xff0c;都会写到这个读写层。 如果删除了容器&#xff0c;也就是删除了其最上面的读写层&…

科技感十足界面模板

科技感界面 在强调简洁的科技类产品相关设计中&#xff0c;背景多数分为&#xff1a;颜色或写实图片两种。 颜色很好理解&#xff0c;大多以深色底为主。强调一种神秘感和沉稳感&#xff0c;同时可以和浅色的文字内容形成很好的对比。 而图片背景的使用&#xff0c;就要求其…

构建高效PythonWeb:GraphQL+Sanic

1.1 简介&#xff1a;在当今快速发展的技术时代&#xff0c;Web应用的性能和灵活性变得越来越重要。在众多技术中&#xff0c;GraphQL和Sanic以其独特的优势脱颖而出。GraphQL&#xff0c;作为一个强大的数据查询语言&#xff0c;为前端和后端之间的通信提供了极大的灵活性。而…

【现代密码学】笔记2 -- 完善保密性《introduction to modern cryphtography》现代密码学原理与协议

【现代密码学】笔记2--完善保密性《introduction to modern cryphtography》 写在最前面2 完善保密性的介绍2.1 定义和基本属性加密方案的组成密钥产生算法 (Gen)加密算法 (Enc)解密算法 (Dec)概率分布独立性 完美保密加密3. 回顾加密词法4. 完美保密&#xff08;**Perfect Sec…

docker打包介绍

最近在做一个开源项目&#xff0c;遇到开发者问各种问题&#xff0c;发现都是系统和软件版本的差异引起的。于是了解了一下docker的使用&#xff0c;发现docker真是个好东东&#xff0c;基本解决了各种版本差异的问题&#xff0c;真正做到了一键部署使用。 先熟悉一下docker里…

阿里云2核4G服务器ecs.e-c1m2.large价格和性能测评

2024年阿里云2核4G服务器优惠价格30元3个月&#xff0c;活动 https://t.aliyun.com/U/bLynLC 配置为云服务器ECS经济型e实例ecs.e-c1m2.large&#xff0c;3M固定带宽&#xff0c;系统盘为40GB ESSD Entry&#xff0c;活动打开如下图&#xff1a; 阿里云2核4G服务器优惠价格30元…

Python武器库开发-武器库篇之C段扫描器开发(四十三)

Python武器库开发-武器库篇之C段扫描器开发(四十三) 在我们进行渗透过程中的信息收集的步骤时&#xff0c;收集资产目标的C段也是非常重要的一部分。 C段是指互联网中的一类IP地址。IP地址是互联网上每台设备的唯一标识符。IP地址由一系列数字组成&#xff0c;通常以点分十进…

【AI视野·今日Sound 声学论文速览 第四十一期】Thu, 4 Jan 2024

AI视野今日CS.Sound 声学论文速览 Thu, 4 Jan 2024 Totally 8 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Multichannel blind speech source separation with a disjoint constraint source model Authors Jianyu Wang, Shanzheng Guan多通道卷积…

2023 CSIG青年科学家会议丨多模态大模型时代下的文档图像处理

近日&#xff0c;由中国图象图形学学会青年工作委员会发起的“第十九届中国图象图形学学会青年科学家会议”在广州召开。 会议面向国际学术前沿与国家战略需求&#xff0c;聚焦最新前沿技术和热点领域&#xff0c;邀请各界专家与青年学者进行总计超200场的高水平学术深度交流&…

漏洞复现--金蝶云星空反序列化远程代码执行

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

无旋转目标检测labelme的json格式转YOLO

# trans_labelme_to_yolo.pyimport cv2 import os import json import shutil import numpy as np from pathlib import Path from glob import globid2cls =

静态网页设计——千姿百色旅游网(HTML+CSS+JavaScript)(dw、sublime Text、webstorm、HBuilder X)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1oe411m7kH/?vd_source5f425e0074a7f92921f53ab87712357b 源码&#xff1a;https://space.bilibili.co…

啊哈c语言——5.9逻辑挑战11(猜数游戏)

计算机会随机地给出0&#xff5e;99之间的一个整数&#xff0c;你能否猜出这个数呢&#xff1f;每猜一次&#xff0c;计算机都会告诉你猜的数是大了还是小了&#xff0c;直到你猜出这个数为止。 首先我们需要解决的第一个问题就是如何让计算机随机地产生一个整数&#xff0c;这…

vue-springboot基于java的实验室安全考试系统

本系统为用户而设计制作实验室安全考试系统&#xff0c;旨在实现实验室安全考试智能化、现代化管理。本实验室安全考试管理自动化系统的开发和研制的最终目的是将实验室安全考试的运作模式从手工记录数据转变为网络信息查询管理&#xff0c;从而为现代管理人员的使用提供更多的…

1- forecasting at scale论文阅读

目录 1. 什么是时间序列2. 什么是时间序列预测3. 时间序列预测的范式4. 时间序列的专有名词介绍5. 时间序列评估 1. 什么是时间序列 按时间先后顺序出现的有序序列 2. 什么是时间序列预测 点预测&#xff1a;预测未来的某一个时间点&#xff0c;它的值到底是多少&#xff0c…

搭建宠物寄养小程序流程

近日&#xff0c;一地宠物寄养需求旺盛&#xff0c;元旦满房&#xff0c;春节几近饱和&#xff0c;一窝难求。随着市场需求的增长&#xff0c;对于很多宠物行业的商家&#xff0c;可以考虑开展宠物寄养服务&#xff0c;尤其是节假日的宠物寄养需求会更高。因此&#xff0c;商家…

我是内网灵活的狗之stack靶场1

首先我们还是老样子 我们先启动这个在win7上面的php工具&#xff0c;也就是启动php服务 然后我们启动kali攻击机 然后打开webshell工具 然后我们先打开MSF工具进行监听 启动msf工具进行监听 12345端口 然后在文件中打开虚拟终端&#xff0c;连接到目标机器内部 start 620.exe…