化繁为简:中介者模式如何管理复杂对象交互

化繁为简:中介者模式如何管理复杂对象交互

中介者模式 是一种行为型设计模式,定义了一个中介者对象,来封装一组对象之间的交互。中介者模式通过将对象之间的交互行为从多个对象中抽离出来,集中封装在一个中介者对象中,从而使各个对象之间的耦合松散,且可以独立地改变它们之间的交互。

核心思想

中介者模式通过引入一个中介者,协调多个对象之间的交互,避免对象之间的直接通信,从而减少对象之间的耦合

中介者模式的组成角色

Mediator(中介者接口)

  • 中介者定义了对象之间交互的接口,负责协调各个对象之间的通信行为。

ConcreteMediator(具体中介者)

  • 实现了 Mediator 接口,协调各具体同事对象之间的交互。它了解所有的同事对象,并通过其实现交互逻辑。

Colleague(同事类)

  • 每个同事对象只知道中介者,不能直接与其他同事对象通信。所有的交互都通过中介者来完成。

ConcreteColleague(具体同事类)

  • 实现了 Colleague 接口,依赖中介者与其他同事对象通信。每个具体同事对象的行为受到中介者的约束。

中介者模式的 UML 类图

在这里插入图片描述

类图解释

  1. Mediator(中介者接口):定义了同事对象之间的通信接口,通常定义 send() 方法来协调通信。
  2. ConcreteMediator(具体中介者)
    • 实现了 Mediator 接口,具体负责管理和协调同事对象之间的通信。它知道所有的具体同事对象,并通过 send() 方法传递消息或协调操作。
    • 它也可以持有具体的同事对象的引用,负责管理这些对象。
  3. Colleague(同事类):抽象类或接口,每个同事对象依赖中介者与其他同事进行交互。它不直接与其他同事对象通信,而是通过中介者通信。
  4. ConcreteColleague1、ConcreteColleague2(具体同事类):实现 Colleague,定义各自的具体操作。同事对象通过中介者协调相互间的通信

工作原理

  1. 集中通信:中介者模式通过引入 Mediator,将多个对象之间的交互逻辑集中到中介者中,使得各个同事类之间的关系变得松散耦合。
  2. 消息传递:同事对象通过调用中介者的 send() 方法进行通信。中介者负责接收和转发消息,并协调其他同事对象的行为。
  3. 解耦同事对象:同事对象之间不直接交互,而是通过中介者来处理。这样一来,各个对象之间的依赖关系被削弱了。

案例:机场塔台与飞机的调度

场景说明

在机场,飞机起飞和降落的调度是一个非常复杂的过程。如果每架飞机都直接与其他飞机进行通信,会导致混乱并增加空中事故的风险。因此,机场有一个控制塔(塔台),它负责协调所有飞机的起飞和降落

控制塔是中介者,飞机之间的所有通信都必须通过控制塔进行。飞机通过塔台来获取是否可以起飞或降落,从而避免与其他飞机发生冲突。

中介者模式的角色在机场塔台场景中的映射:

  1. Mediator(中介者接口):机场控制塔,负责协调所有飞机的起飞和降落。
  2. ConcreteMediator(具体中介者):具体实现的控制塔,协调飞机的飞行状态。
  3. Colleague(同事类):抽象飞机类,代表参与通信的对象(飞机)。
  4. ConcreteColleague(具体同事类):具体的飞机类,通过控制塔来决定起飞或降落。

在这里插入图片描述

代码实现:机场塔台调度系统

Step 1: 定义中介者接口

中介者接口定义了调度方法,用于协调飞机之间的通信。

// 中介者接口:塔台
public interface Mediator {
    void notify(String message, Airplane airplane);
}

Step 2: 实现具体的中介者

ControlTower 类是具体的中介者,它负责接收飞机的状态并通知其他飞机,确保起飞和降落顺序的安全。

import java.util.ArrayList;
import java.util.List;

// 具体中介者:控制塔
public class ControlTower implements Mediator {
    private List<Airplane> airplanes;

    public ControlTower() {
        this.airplanes = new ArrayList<>();
    }

    public void registerAirplane(Airplane airplane) {
        airplanes.add(airplane);
    }

    @Override
    public void notify(String message, Airplane airplane) {
        for (Airplane a : airplanes) {
            if (a != airplane) {
                a.receive(message);  // 通知其他飞机
            }
        }
    }
}

Step 3: 定义飞机抽象类

飞机类通过中介者来发送和接收信息,而不直接与其他飞机通信。

// 飞机抽象类
public abstract class Airplane {
    protected Mediator mediator;
    protected String name;

    public Airplane(Mediator mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    }

    public abstract void send(String message);
    public abstract void receive(String message);
}

Step 4: 实现具体飞机类

具体飞机类实现了 send()receive() 方法,通过塔台来发送和接收消息。

Boeing737 类

// 具体飞机:Boeing 737
public class Boeing737 extends Airplane {

    public Boeing737(Mediator mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void send(String message) {
        System.out.println(this.name + " sends message: " + message);
        mediator.notify(message, this);  // 通过塔台发送消息
    }

    @Override
    public void receive(String message) {
        System.out.println(this.name + " receives message: " + message);
    }
}

AirbusA320 类

// 具体飞机:Airbus A320
public class AirbusA320 extends Airplane {

    public AirbusA320(Mediator mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void send(String message) {
        System.out.println(this.name + " sends message: " + message);
        mediator.notify(message, this);  // 通过塔台发送消息
    }

    @Override
    public void receive(String message) {
        System.out.println(this.name + " receives message: " + message);
    }
}

Step 5: 测试中介者模式

通过 ControlTower 来协调 Boeing737AirbusA320 之间的通信,确保飞机的起飞和降落顺序。

public class MediatorPatternDemo {
    public static void main(String[] args) {
        // 创建控制塔
        ControlTower tower = new ControlTower();

        // 创建飞机并注册到塔台
        Airplane boeing737 = new Boeing737(tower, "Boeing 737");
        Airplane airbusA320 = new AirbusA320(tower, "Airbus A320");

        tower.registerAirplane(boeing737);
        tower.registerAirplane(airbusA320);

        // 飞机发送消息
        boeing737.send("Requesting permission to land.");
        airbusA320.send("Requesting permission to take off.");
    }
}

输出结果

Boeing 737 sends message: Requesting permission to land.
Airbus A320 receives message: Requesting permission to land.
Airbus A320 sends message: Requesting permission to take off.
Boeing 737 receives message: Requesting permission to take off.

中介者模式在机场塔台场景中的工作原理

  1. 集中通信:所有的飞机(同事类)不直接通信,而是通过控制塔(中介者)进行协调。每架飞机都通过塔台发送和接收消息。
  2. 消息传递:当一架飞机发送起飞或降落请求时,塔台负责通知其他飞机,并保证飞行安全和秩序。
  3. 降低耦合性:飞机之间不直接通信,所有交互通过塔台完成,从而降低了飞机之间的耦合,增强了系统的灵活性和扩展性。

SpringMVC 中的 应用

Spring Framework 中,DispatcherServlet 作为前端控制器,实际上也承担了类似于中介者的作用。它在 Spring MVC 架构中负责协调不同组件(如控制器、视图解析器和处理器)的交互。

原理
  • DispatcherServlet 作为一个统一的请求分发器,负责接收 HTTP 请求,并根据请求的 URL 或其他条件,将请求分发给适当的处理器(如 @Controller 的方法)。它并不直接参与具体的请求处理,而是协调多个组件来完成请求-响应的流程。
  • 控制器、视图解析器、处理器等组件之间不直接通信,而是通过 DispatcherServlet 进行交互。
// DispatcherServlet 伪代码,简化示例
public class DispatcherServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 根据请求查找对应的控制器
        Handler handler = getHandler(request);
        
        // 调用控制器处理请求
        ModelAndView mv = handler.handleRequest(request, response);
        
        // 解析视图并返回响应
        render(mv, response);
    }
}

在这里,DispatcherServlet 类似于中介者,协调多个组件之间的交互,不同的控制器和视图解析器不直接互相通信,而是通过 DispatcherServlet 进行处理。

中介者模式的优缺点与应用场景总结

优点:

  1. 降低对象之间的耦合性
    • 中介者模式通过引入中介者,使多个对象之间的依赖关系转变为与中介者的依赖,减少了对象之间的直接交互,降低了系统的耦合度。
  2. 简化对象之间的通信
    • 所有通信都通过中介者集中管理,使得系统结构更加清晰,逻辑集中,尤其在多方通信的复杂系统中,简化了交互逻辑。
  3. 符合开闭原则
    • 中介者模式可以方便地扩展或修改交互逻辑,而不影响各个同事对象。可以通过修改中介者来增加或调整各对象之间的交互。
  4. 提高系统的灵活性
    • 当需要增加新的对象或修改对象之间的交互行为时,可以通过中介者进行控制,增强了系统的扩展性和灵活性。

缺点:

  1. 中介者可能变得复杂
    • 随着系统中同事对象的增多,中介者需要处理的交互逻辑也会变得越来越复杂,可能导致中介者变得难以维护,形成一个“上帝对象”。
  2. 不适合简单场景
    • 如果对象之间的交互非常简单,使用中介者模式会引入不必要的复杂性,增加维护成本。

应用场景:

  1. 复杂对象交互的系统
    • 在多个对象之间存在复杂交互的系统中,中介者模式非常适用。例如,GUI 控件交互(如按钮、文本框、下拉菜单等)可以通过中介者来管理。
  2. 消息队列系统
    • 在消息队列(如 JMS)中,中介者管理生产者和消费者之间的消息传递,解耦了消息的发送和接收,避免直接通信。
  3. 事件驱动系统
    • 在事件驱动架构中,事件发布者和监听者之间的通信可以通过中介者来协调,避免对象之间的紧密耦合。例如,Spring 的事件驱动机制利用 ApplicationEventPublisherApplicationListener 解耦了事件发布和处理。
  4. 航空管制系统
    • 像机场塔台这种需要协调多架飞机起降的系统,中介者可以集中管理对象的行为,保证复杂交互的有序进行。

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

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

相关文章

【开源】 mRemoteNG 一键搞定!推荐一款强大的.NET多协议远程连接管理器

今天给大家推荐一款.NET开发的多协议、选项卡式远程连接管理器mRemoteNG。 mRemoteNG 是 mRemote 的一个分支&#xff1a;一个开源的、标签式的、多协议的、用于 Windows 的远程连接管理器。 mRemoteNG是一个开源的Windows远程连接管理器&#xff0c;它支持多种协议&#xff0c…

基于小安派AiPi-Eyes-Rx的N合1触摸屏游戏

基于小安派AiPi-Eyes-Rx的N合1触摸屏游戏 目前存在的游戏&#xff1a; 植物大战僵尸&#xff1a;demos/pvz羊了个羊&#xff1a;demos/yang消消乐&#xff1a;demos/xiaoxiaole华容道&#xff1a;demos/huarongdao PVZ功能展示可见&#xff1a; 羊了个羊&#xff1a; 消消…

开闭原则(OCP)

开闭原则&#xff08;OCP&#xff09;&#xff1a;Open Closed Princide&#xff1a;对扩展开放&#xff0c;对修改关闭。在程序需要进行拓展的时候&#xff0c;不能去修改原有代码&#xff0c;实现一个热插拔的效果。 简言之&#xff0c;是为了使程序的扩展性更好&#xff0c;…

【STM32】 TCP/IP通信协议(1)

一、前言 TCP/IP是干啥的&#xff1f;它跟SPI、IIC、CAN有什么区别&#xff1f;它如何实现stm32的通讯&#xff1f;如何去配置&#xff1f;为了搞懂这些问题&#xff0c;查询资料可解决如下疑问&#xff1a; 1.为什么要用以太网通信? 以太网(Ethernet) 是指遵守 IEEE 802.3 …

【React】组件基础使用

1. react组件 在react中&#xff0c;组件就是首字母大写的函数&#xff0c;内部存放了组件的逻辑、UI&#xff0c;渲染组件只需要把组件当成标签书写。 使用组件有两种方式&#xff1a;自闭和 、成对标签 function App() {// 定义组件function Component() {return <div&…

快手一面:给定一棵二叉树,要求将其转换为其镜像?

目录标题 题解&#xff1a;二叉树的镜像&#xff08;Invert Binary Tree&#xff09;问题描述示例解题思路代码实现详细分析复杂度分析优点注意事项&#x1f495; 题解&#xff1a;二叉树的镜像&#xff08;Invert Binary Tree&#xff09; 问题描述 给定一棵二叉树&#xff…

Elasticsearch——介绍、安装与初步使用

目录 1.初识 Elasticsearch1.1.了解 ES1.1.1.Elasticsearch 的作用1.1.2.ELK技术栈1.1.3.Elasticsearch 和 Lucene1.1.4.为什么不是其他搜索技术&#xff1f;1.1.5.总结 1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引1.2.3.正向和倒排 1.3.Elasticsearch 的一些概念1.3.1.文档和字…

MISC - 第二天(wireshark,base64解密图片,zip文件伪加密,LSB二进制最低位,ARCHPR工具)

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天给大家讲解杂项 乌镇峰会种图 使用了stegsolve工具&#xff0c;查看更多信息 发现flag信息 更改为html后缀flag{97314e7864a8f62627b26f3f998c37f1} wireshark 看题目是 分析pacp数据包&#xff0c;通过网站登录…

kubernetes K8S 结合 Istio 实现流量治理

目录 1.Istio介绍&#xff1f; 1.1 Istio是什么&#xff1f; 1.2 Istio流量管理 1.2.1 熔断 1.2.2 超时 1.2.3 重试 2.Istio架构 3.istio组件详解 3.1 Pilot 3.2 Envoy 3.3 Citadel 3.4 Galley 3.5 Ingressgateway 3.5 egressgateway 扩展、k8s1.23及1.23以下版…

每日算法2(翻转链表)

链接. - 力扣&#xff08;LeetCode&#xff09; 第一种 先来讲下最简单的算法&#xff0c;创建一个新链表&#xff0c;将原链表的元素挨个头插到新链表上&#xff0c;就实现了顺序表的逆转&#xff0c;这里就不示例代码了&#xff0c;在之前的链表有提及。 第二种 可以试试…

初写MySQL四张表:(4/4)

进度条很喜人&#xff0c;你是否已经修炼到这一步了呢&#xff1f; 初写MySQL四张表:(1/4)-CSDN博客 初写MySQL四张表:(2/4)_数据库表样例-CSDN博客 初写MySQL四张表:(3/4)-CSDN博客 若现在你已经有了前面的基础&#xff0c;那就正式开始吧。 四张表&#xff1a; 这次在实现…

JavaWeb美食推荐管理系统

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 spring-mybatis.xml3.5 spring-mvc.xml3.5 login.jsp 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优…

从理论到实践:解锁《数字化专业知识体系》助力企业数字化转型的落地之道

全面解码数字化转型——从理论构想到实践落地 在全球数字化浪潮的推动下&#xff0c;企业正面临前所未有的变革压力。虽然数字化转型的概念已经深入人心&#xff0c;但将其从战略蓝图转化为实际成果的过程仍充满挑战。《数字化专业知识体系》&#xff08;《Towards a Digital …

鸿蒙操作系统(HarmonyOS)生态与机遇

HarmonyOS技术特点 鸿蒙操作系统&#xff08;HarmonyOS&#xff09;是华为公司开发的一款面向全场景的分布式操作系统。 架构特点&#xff1a; 分布式架构&#xff1a;这是鸿蒙系统的显著特点之一。它支持跨设备无缝协同体验&#xff0c;使不同设备能够快速连接、能力互助和资…

认知战认知作战:认知战目标对手分析,你需要知道的目标对手分析SOP

认知战认知作战&#xff1a;认知战目标对手分析&#xff0c;你需要知道的目标对手分析SOP 认知战认知作战&#xff1a;认知战目标对手分析你需要知道的目标对手分析SOP 关键词&#xff1a;认知战, 目标对手分析, 数据情报搜集, 自我审视, 洞悉对手, 精准攻击策略, 行动规划, …

基于等保浅谈服务器端和客户端的身份鉴别双向验证

等保云计算扩展要求 身份鉴别:当远程管理云计算平台中设备时&#xff0c;管理终端和云计算平台之间应建立双向身份验证机制。 单项认证和双向认证介绍 单向认证一般是指客户端确认服务端身份&#xff0c;而双向认证一般是指客户端和服务器端都需要验证对方的身份。双向认证的…

记录-java web 生成并下载zip文件

java生成zip文件&#xff0c;zip文件分两种&#xff1a;一种是包含文件夹、一种是不包含文件夹 生成zip文件的方式 ZipOutputStream zipOutputStream new ZipOutputStream(response.getOutputStream());// 文件夹名称String folder "download/";ZipEntry ze new Z…

怎样将latex文档转为word文档?

通常我们使用latex撰写论文&#xff0c;但有时也需要转为word文档方便其它人使用。转换过程中需要处理的内容包括3个部分&#xff1a;文字、图片、公式以及表格。 最简单的转换方式&#xff1a;latex编译成pdf文档&#xff0c;使用wps转换为word格式即可。这样转换的文档&…

你以为建站很复杂?Baklib 5分钟解决你的痛点

你以为建站很复杂&#xff1f;Baklib 5分钟解决你的痛点&#xff01; 在这个“快节奏”的互联网时代&#xff0c;想要快速搭建一个网站是很多人的刚需。今天我要介绍的&#xff0c;就是如何利用Baklib的CMS/Wiki模板&#xff0c;五分钟内让你的网站“横空出世”。废话不多说&am…

双token无感刷新(vue3+node.js)

无感刷新的基本原理 使用刷新令牌&#xff08;refresh token&#xff09;&#xff1a; ○ 应用程序在首次登录成功后会获得一个访问令牌&#xff08;access token&#xff09;和一个刷新令牌&#xff08;refresh token&#xff09;。 ○ 访问令牌通常有较短的有效期&#xff0…