设计模式-调停者模式

设计模式专栏

    • 模式介绍
    • 模式特点
    • 应用场景
    • 调停者模式与命令模式的比较
    • 代码示例
      • Java实现调停者模式
      • Python实现调停者模式
    • 调停者模式在spring中的应用


模式介绍

调停者模式是一种软件设计模式,主要用于模块间的解耦,通过避免对象之间显式的互相指向,降低耦合度。这种模式通常用于解决多个对象之间重复访问、无规律性、交互方式复杂且通常存在非结构依赖的问题。

在调停者模式中,通常会有一个抽象调停者(Mediator)类,它定义了同事对象与调停者对象之间的接口,主要方法是一个或多个事件方法。具体调停者(ConcreteMediator)类则实现了抽象调停者所声明的事件方法,负责具体的协调各同事对象的交互关系。此外,还有一个抽象同事类(Colleague),它定义了调停者到同事对象的接口,同事对象只知道调停者而不知道其余的同事对象。

调停者模式将多对多的相互作用转化为一对多的相互作用,将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。通过使用中介对象封装一系列的对象交互,各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。这种模式有助于降低系统的复杂性,提高可维护性和可扩展性。

在这里插入图片描述

模式特点

调停者模式的特点主要包括以下几个方面:

  1. 封装交互 :调停者模式将一系列对象之间的交互封装在一个单独的调停者对象中,使得这些对象之间不需要相互明显引用,从而降低了耦合度。
  2. 抽象化 :调停者模式将对象的行为和协作抽象化,将小尺度的行为上与其他对象的相互作用分开处理,使得对象之间的关系更加易于维护和理解。
  3. 转化交互方式 :调停者模式将多对多的相互作用转化为一对多的相互作用,使得对象之间的关系更加清晰和易于管理。
  4. 提供可扩展性 :调停者模式为同事对象提供可扩展性,使得系统可以在不改变现有类的情况下进行扩展。
  5. 控制集中化 :调停者模式将控制集中在一个对象上,可能会使得这个对象变得复杂且难于管理。
  6. 适用场景 :调停者模式适用于解决多个对象之间存在复杂交互、行为变化多样且不规律的问题,尤其在涉及不同对象的协同工作、请求分发、业务逻辑协调等场景中能够发挥重要作用。

调停者模式通过封装交互、抽象化、转化交互方式等特点,降低了系统的耦合度,使得对象间的交互行为更加清晰和易于管理,提高了系统的可维护性和可扩展性。同时,需要注意控制集中化的问题,并合理选择适用场景。

在这里插入图片描述

应用场景

调停者模式的应用场景主要包括:

  1. 当一个系统内部存在许多类,它们之间相互调用以完成一系列功能时,一旦某个类发生问题或需要进行修改,这可能会导致对所有调用它的类产生影响,此时就可以采用调停者模式。通过引入调停者类来封装所有类之间的交互,使原本复杂的网状结构变得简单,形成星型结构,降低了类与类之间的耦合度。
  2. 在处理对象之间存在复杂交互、行为变化多样且不规律的情况下,调停者模式可以起到很好的作用。
  3. 存在非结构化依赖的情况下,使用调停者模式能够简化对象的相互依赖关系,降低维护和扩展的难度。
  4. 涉及不同对象的协同工作、请求分发、业务逻辑协调等场景,也可以考虑使用调停者模式。

调停者模式能够将对象间的直接调用解耦,使得对象间的交互行为集中化管理,方便维护和扩展。然而,这种模式也有其局限性,如可能导致控制集中化,使得调停者类变得复杂且难于管理。在实际应用中,需要根据具体问题来决定是否采用调停者模式。

在这里插入图片描述

调停者模式与命令模式的比较

调停者模式与命令模式是两种不同的软件设计模式,它们有不同的应用场景和特点。

调停者模式主要用于解决多个对象之间的交互问题,通过引入一个调停者对象来封装和协调各个对象之间的交互,降低系统的耦合度,使得对象间的交互行为更加清晰和易于管理。其主要特点是能够将多个对象的交互行为集中在一个对象中管理,使得对象的相互依赖关系变得简单,降低系统的复杂性和维护成本。

命令模式是一种行为型设计模式,它主要处理在不同对象之间指定责任的细节,描述对象间的通信机制,定义一种机制以便在运行时根据不同的对象选择不同的逻辑。其主要特点是将请求或操作封装到一个对象中,通过使用命令对象来请求一个操作的对象与知道怎么执行一个操作的对象解耦,使得请求可以被取消、恢复或者组合。

调停者模式与命令模式的不同点在于,调停者模式主要关注多个对象之间的交互解耦,而命令模式主要关注请求或操作的封装、排队和撤销等控制功能。此外,调停者模式通常用于协调对象之间的交互行为,而命令模式通常用于处理请求或操作的控制流程。

相同点方面,调停者模式和命令模式都关注降低系统的耦合度,提高系统的可维护性和可扩展性。它们都通过封装请求或操作来实现对请求的控制,包括排队、顺序执行和撤销等。同时,它们都需要在请求的发送者和接收者之间建立一种抽象的通信机制,以便在运行时根据不同的对象选择不同的逻辑。

调停者模式和命令模式在应用场景、作用和使用特点等方面存在明显的差异,但两者在抽象通信机制和降低系统耦合度方面有一定的相似性。在实际应用中,根据具体的问题和需求选择合适的模式是重要的。

在这里插入图片描述

代码示例

Java实现调停者模式

以下是一个简单的Java实现调停者模式的示例:

// 抽象调停者
interface Mediator {void register(Colleague colleague);void handleMessage(Colleague colleague, Object message);
}// 具体调停者
class ConcreteMediator implements Mediator {private Map<Colleague, Handler> handlers = new HashMap<>();@Overridepublic void register(Colleague colleague) {handlers.put(colleague, new Handler(colleague));}@Overridepublic void handleMessage(Colleague colleague, Object message) {Handler handler = handlers.get(colleague);if (handler != null) {handler.handleMessage(message);}}class Handler {private Colleague colleague;public Handler(Colleague colleague) {this.colleague = colleague;}public void handleMessage(Object message) {// 处理消息逻辑,根据具体需求实现System.out.println("ConcreteMediator handled message for Colleague " + colleague);}}
}// 抽象同事类
interface Colleague {void setMediator(Mediator mediator);void sendMessage(Object message);
}// 具体同事类1
class ConcreteColleague1 implements Colleague {private Mediator mediator;private String name;public ConcreteColleague1(String name) {this.name = name;}@Overridepublic void setMediator(Mediator mediator) {this.mediator = mediator;}@Overridepublic void sendMessage(Object message) {mediator.handleMessage(this, message);}@Overridepublic String toString() {return name;}
}// 具体同事类2
class ConcreteColleague2 implements Colleague {private Mediator mediator;private String name;public ConcreteColleague2(String name) {this.name = name;}@Overridepublic void setMediator(Mediator mediator) {this.mediator = mediator;}@Overridepublic void sendMessage(Object message) {mediator.handleMessage(this, message);}@Overridepublic String toString() {return name;}
}

Python实现调停者模式

以下是Python实现调停者模式的示例代码:

from abc import ABC, abstractmethod# 抽象调停者
class Mediator(ABC):@abstractmethoddef register(self, colleague):pass@abstractmethoddef handle_message(self, colleague, message):pass# 具体调停者
class ConcreteMediator(Mediator):def __init__(self):self.colleagues = []def register(self, colleague):self.colleagues.append(colleague)def handle_message(self, colleague, message):for c in self.colleagues:if c != colleague:c.send_message(message)# 抽象同事类
class Colleague(ABC):@abstractmethoddef set_mediator(self, mediator):pass@abstractmethoddef send_message(self, message):pass# 具体同事类1
class ConcreteColleague1(Colleague):def __init__(self, name):self.name = nameself.mediator = Nonedef set_mediator(self, mediator):self.mediator = mediatormediator.register(self)def send_message(self, message):self.mediator.handle_message(self, message)print(f"{self.name} sent message: {message}")# 具体同事类2
class ConcreteColleague2(Colleague):def __init__(self, name):self.name = nameself.mediator = Nonedef set_mediator(self, mediator):self.mediator = mediatormediator.register(self)def send_message(self, message):self.mediator.handle_message(self, message)print(f"{self.name} sent message: {message}")

在这里插入图片描述

调停者模式在spring中的应用

在Spring框架中,调停者模式可以应用于许多场景,其中最常见的是事件监听和通知机制。Spring的事件监听器模式就是一个典型的调停者模式的实现。

在Spring中,可以使用ApplicationListener接口和ApplicationEvent类来实现事件监听和通知。ApplicationListener接口定义了一个onApplicationEvent方法,该方法在接收到事件时会触发。ApplicationEvent类是事件的抽象类,它定义了一些常用的方法,如获取事件的来源和时间等。

具体实现时,首先需要创建一个继承自ApplicationEvent的事件类,例如:

public class MyCustomEvent extends ApplicationEvent {private String message;public MyCustomEvent(Object source, String message) {super(source);this.message = message;}public String getMessage() {return message;}
}

然后,创建一个实现ApplicationListener接口的监听器类,例如:

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class MyCustomEventListener implements ApplicationListener<MyCustomEvent> {@Overridepublic void onApplicationEvent(MyCustomEvent event) {System.out.println("Received MyCustomEvent - " + event.getMessage());}
}

最后,在需要发布事件的类中,使用ApplicationContextpublishEvent方法发布事件:

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;@Component
public class EventPublisher {private ApplicationContext applicationContext;public EventPublisher(ApplicationContext applicationContext) {this.applicationContext = applicationContext;}public void publishEvent() {String message = "Hello, Spring!";MyCustomEvent event = new MyCustomEvent(this, message);applicationContext.publishEvent(event);}
}

在上面的示例中,EventPublisher组件发布了一个自定义的事件,所有实现了MyCustomEventListener接口的组件都会接收到该事件,并执行相应的逻辑。这就是Spring中调停者模式的典型应用。

在这里插入图片描述

设计模式-过滤器模式

设计模式-门面模式

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

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

相关文章

PyTorch常用工具(2)预训练模型

文章目录 前言2 预训练模型 前言 在训练神经网络的过程中需要用到很多的工具&#xff0c;最重要的是数据处理、可视化和GPU加速。本章主要介绍PyTorch在这些方面常用的工具模块&#xff0c;合理使用这些工具可以极大地提高编程效率。 由于内容较多&#xff0c;本文分成了五篇…

Pytest 项目结合Jenkins

一、window安装centos7虚拟机 参考网上其他教程 二、Linux安装Jenkins 进入jenkins.io网址&#xff0c;点击download&#xff0c;选择CentOS版本 1、Linux中安装java环境和git Jenkins的运行需要java环境&#xff1b;安装git是为代码上传给仓库做准备&#xff1b; yum - y…

浅谈冯诺依曼体系和操作系统

&#x1f30e;冯诺依曼体系结构 文章目录 冯诺依曼体系结构 认识冯诺依曼体系结构       硬件分类       各个硬件的简单认识         输入输出设备         中央处理器         存储器 关于内存 对冯诺依曼体系的理解 操作系统 操作系统…

linux中用户账号和权限管理

一.Linux 用户分三类 1.普通用户 权限受限制的用户 2. 超级管理员 拥有至高无上权限 3. 程序用户 不是给人使用的&#xff0c;给程序用 运行程序不能使用超级管理员&#xff0c;从安全考虑 超级管理员 uid 为0 普通用户 1000~60000 &#xff0…

Python实现的面部健康特征识别系统

Python实现的面部健康特征识别系统 引言1. 数据集获取与准备2. 模型训练3. Flask框架的应用4. 前台识别测试界面 结论与展望 引言 本文将介绍一个基于Python的面部健康特征判别系统&#xff0c;该系统利用互联网获取的公开数据集&#xff0c;分为健康、亚健康和不健康三个类别…

传统船检已经过时?AR智慧船检来助力!!

想象一下&#xff0c;在茫茫大海中&#xff0c;一艘巨型货轮正缓缓驶过。船上的工程师戴着一副先进的AR眼镜&#xff0c;他们不再需要反复翻阅厚重的手册&#xff0c;一切所需信息都实时显示在眼前。这不是科幻电影的场景&#xff0c;而是智慧船检技术带来的现实变革。那么问题…

零基础打靶—BC1靶场

一、打靶的主要五大步骤 1.确定目标&#xff1a;在所有的靶场中&#xff0c;确定目标就是使用nmap进行ip扫描&#xff0c;确定ip即为目标&#xff0c;其他实战中确定目标的方式包括nmap进行扫描&#xff0c;但不局限于这个nmap。 2.常见的信息收集&#xff1a;比如平常挖洞使用…

【损失函数】SmoothL1Loss 平滑L1损失函数

1、介绍 torch.nn.SmoothL1Loss 是 PyTorch 中的一个损失函数&#xff0c;通常用于回归问题。它是 L1 损失和 L2 损失的结合&#xff0c;旨在减少对异常值的敏感性。 loss_function nn.SmoothL1Loss(reductionmean, beta1.0) 2、参数 size_average (已弃用): 以前用于确定是…

LabVIEW在大型风电机组状态监测系统开发中的应用

LabVIEW在大型风电机组状态监测系统开发中的应用 风电作为一种清洁能源&#xff0c;近年来在全球范围内得到了广泛研究和开发。特别是大型风力发电机组&#xff0c;由于其常常位于边远地区如近海、戈壁、草原等&#xff0c;面临着恶劣自然环境和复杂设备运维挑战。为了提高风电…

Everything 搜索

正则表达式Regex 首先需要开启 Everything 工具在&#xff08;字符串&#xff09;查找时&#xff0c;对正则表达式功能的支持&#xff1a; 需要在【菜单栏】⇒ 【Search】⇒ 勾选【Enable Regex】 查看Everything 支持的语法:

Java安装详细教程

文章目录 一、JDK 下载 和 安装1.1 选择 Java版本1.2 下载 JDK 二、 配置环境变量2.1 配置环境变量的原因2.2 配置环境变量2.3 验证配置是否成功 参考资料 一、JDK 下载 和 安装 1.1 选择 Java版本 访问 Oracle 官方网站的 Java 下载页面Java Archive | Oracle。 在 “Java …

MAC 中多显示器的设置(Parallels Desktop)

目录 一、硬件列表&#xff1a; 二、线路连接&#xff1a; 三、软件设置&#xff1a; 1. 设置显示器排列位置及显示参数 2. 分别设置外接显示器为&#xff1a;扩展显示器&#xff0c;内建显示器为主显示器 3. 设置Parallels Desktop屏幕参数 四、结果 一、硬件列表&a…

005、数据类型

1. 关于数据类型 Rust中&#xff0c;每个值都有其特定的数据类型&#xff0c;Rust会根据数据的类型来决定如何处理它们。 Rust是一门静态类型语言&#xff0c;它在编译程序的过程中就需要知道所有变量的具体类型。在大部分情况下&#xff0c;编译器可以根据我们如何绑定、使用变…

【Redis-10】Redis集群的实现原理和实践

Redis集群是Redis提供的分布式数据库方案&#xff0c;通过分片来进行数据共享&#xff0c;实现复制和故障转移的功能。 1. Redis集群节点 一个Redis集群由多个节点组成&#xff0c;多个节点可以通过命令实现连接&#xff0c;由独立状态转为集群状态&#xff0c;命令是cluster …

《Python机器学习原理与算法实现》学习笔记

以下为《Python机器学习原理与算法实现》&#xff08;杨维忠 张甜 著 2023年2月新书 清华大学出版社&#xff09;的学习笔记。 根据输入数据是否具有“响应变量”信息&#xff0c;机器学习被分为“监督式学习”和“非监督式学习”。 “监督式学习”即输入数据中即有X变量&…

WPF 消息日志打印帮助类:HandyControl+NLog+彩色控制台打印+全局异常捕捉

文章目录 前言相关文章Nlog配置HandyControl配置简单使用显示效果文本内容 全局异常捕捉异常代码运行结果 前言 我将简单的HandyControl的消息打印系统和Nlog搭配使用&#xff0c;简化我们的代码书写 相关文章 .NET 控制台NLog 使用 WPF-UI HandyControl 控件简单实战 C#更改…

10TB海量JSON数据从OSS迁移至MaxCompute

前提条件 开通MaxCompute。 在DataWorks上完成创建业务流程&#xff0c;本例使用DataWorks简单模式。详情请参见创建业务流程。 将JSON文件重命名为后缀为.txt的文件&#xff0c;并上传至OSS。本文中OSS Bucket地域为华东2&#xff08;上海&#xff09;。示例文件如下。 {&qu…

Unity坦克大战开发全流程——结束场景——通关界面

结束场景——通关界面 就照着这样来拼 写代码 hideme不要忘了 修改上一节课中的代码

[2024区块链开发入门指引] - 比特币运行原理

一份为小白用户准备的免费区块链基础教程 工欲善其事,必先利其器 Web3开发中&#xff0c;各种工具、教程、社区、语言框架.。。。 种类繁多&#xff0c;是否有一个包罗万象的工具专注与Web3开发和相关资讯能毕其功于一役&#xff1f; 参见另一篇博文&#x1f449; 2024最全面…

数据结构:第7章:查找(复习)

目录 顺序查找&#xff1a; 折半查找&#xff1a; 二叉排序树&#xff1a; 4. (程序题) 平衡二叉树&#xff1a; 顺序查找&#xff1a; ASL 折半查找&#xff1a; 这里 j 表示 二叉查找树的第 j 层 二叉排序树&#xff1a; 二叉排序树&#xff08;Binary Search Tree&…