设计模式-调停者模式

设计模式专栏

    • 模式介绍
    • 模式特点
    • 应用场景
    • 调停者模式与命令模式的比较
    • 代码示例
      • 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<>();

    @Override
    public void register(Colleague colleague) {
        handlers.put(colleague, new Handler(colleague));
    }

    @Override
    public 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;
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void sendMessage(Object message) {
        mediator.handleMessage(this, message);
    }

    @Override
    public String toString() {
        return name;
    }
}

// 具体同事类2
class ConcreteColleague2 implements Colleague {
    private Mediator mediator;
    private String name;

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

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void sendMessage(Object message) {
        mediator.handleMessage(this, message);
    }

    @Override
    public String toString() {
        return name;
    }
}

Python实现调停者模式

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

from abc import ABC, abstractmethod

# 抽象调停者
class Mediator(ABC):
    @abstractmethod
    def register(self, colleague):
        pass

    @abstractmethod
    def 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):
    @abstractmethod
    def set_mediator(self, mediator):
        pass

    @abstractmethod
    def send_message(self, message):
        pass

# 具体同事类1
class ConcreteColleague1(Colleague):
    def __init__(self, name):
        self.name = name
        self.mediator = None

    def set_mediator(self, mediator):
        self.mediator = mediator
        mediator.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 = name
        self.mediator = None

    def set_mediator(self, mediator):
        self.mediator = mediator
        mediator.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> {
    @Override
    public 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中调停者模式的典型应用。

在这里插入图片描述

设计模式-过滤器模式

设计模式-门面模式

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

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

相关文章

解决阿里云远程连接yum无法安装问题(Ubuntu 22.04)

解决阿里云远程连接yum无法安装问题&#xff08;Ubuntu 22.04&#xff09; 第一步 进入阿里云远程连接后&#xff0c;尝试安装宝塔面包第二步&#xff1a;尝试更新软件包等一些列操作第三步&#xff1a;完成上述操作之后&#xff0c;尝试安装yum第四步&#xff1a;尝试更换清华…

计算机网络【Google的TCP BBR拥塞控制算法深度解析】

Google的TCP BBR拥塞控制算法深度解析 宏观背景下的BBR 慢启动、拥塞避免、快速重传、快速恢复&#xff1a; 说实话&#xff0c;这些机制完美适应了1980年代的网络特征&#xff0c;低带宽&#xff0c;浅缓存队列&#xff0c;美好持续到了2000年代。 随后互联网大爆发&#x…

stm32 HAL库 4096线ABZ编码器

[TOC]目录 ABZ编码器 4096线 买的是这个 AB相代表计数方向&#xff0c;Z代表过零点 cubemx配置 定时器Encoder 也可以选上DMA 中断 Z相GPIO中断 找一个空闲管脚 打开对应中断 代码 不用DMA int main(void) {short Enc_cnt 0;HAL_TIM_Encoder_Start_IT(&ht…

4.33 构建onnx结构模型-Expand

前言 构建onnx方式通常有两种&#xff1a; 1、通过代码转换成onnx结构&#xff0c;比如pytorch —> onnx 2、通过onnx 自定义结点&#xff0c;图&#xff0c;生成onnx结构 本文主要是简单学习和使用两种不同onnx结构&#xff0c; 下面以 Expand 结点进行分析 方式 方法一…

最优轨迹生成(二)—— 无约束BVP轨迹优化

本系列文章是学习深蓝学院-移动机器人运动规划课程第五章最优轨迹生成 过程中所记录的笔记&#xff0c;本系列文章共包含四篇文章&#xff0c;依次介绍了微分平坦特性、无约束BVP轨迹优化、无约束BIVP轨迹优、 带约束轨迹优化等内容 本系列文章链接如下&#xff1a; 最优轨迹生…

8868体育助力意甲罗马俱乐部 迪巴拉有望付出

8868体育助力意甲罗马俱乐部 迪巴拉有望付出 意甲罗马俱乐部是8868体育合作球队之一&#xff0c;本赛季&#xff0c;在意甲第14轮的比赛中&#xff0c;罗马客场2-1战胜萨索洛&#xff0c;积分上升到意甲第4位。 有报道称&#xff0c;迪巴拉在对阵佛罗伦萨的比赛中受伤&#xff…

操作注册表

命令说明&#xff1a; regedit&#xff08;快速打开注册表命令&#xff09; reg query 显示注册表的所有子项和值 reg delete 从注册表删除项或值 /v EntryName &#xff08;注册表项和子项名称&#xff09; 删除子项下的特定项。如果未指定子项&#xff0c;则将删除子项…

将本地工作空间robot_ws上传到gitee仓库

git config --global user.name "geniusChinaHN" git config --global user.email "12705243geniuschinahnuser.noreply.gitee.com" cd ~/robot_ws #git init#创建原始仓库时候用 git add . git commit -m "上传文件内容描述" #git remote add r…

ISO27001 信息安全管理体系认证,让你的信息安全无懈可击

你是否担心过自己的个人信息被泄露&#xff1f;你的企业是否因为信息安全问题而遭受过损失&#xff1f;如果是&#xff0c;那么你一定不能错过 ISO27001 信息安全管理体系认证&#xff01; &#x1f31f;什么是 ISO27001 认证&#xff1f; ISO27001 是由国际标准化组织&#xf…

设计模式之初始设计模式和UML图

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

SNMP获取Linux系统信息

snmp测试 snmpwalk -v 2c -c public123 192.168.227.133 system[rootlocalhost ~]# snmpwalk -v 2c -c public123 192.168.227.133 system SNMPv2-MIB::sysDescr.0 STRING: Linux localhost.localdomain 5.10.0-60.18.0.50.oe2203.x86_64 #1 SMP Wed Mar 30 03:12:24 UTC 202…

2022年全球运维大会(GOPS深圳站)-核心PPT资料下载

一、峰会简介 GOPS 主要面向运维行业的中高端技术人员&#xff0c;包括运维、开发、测试、架构师等群体。目的在于帮助IT技术从业者系统学习了解相关知识体系&#xff0c;让创新技术推动社会进步。您将会看到国内外知名企业的相关技术案例&#xff0c;也能与国内顶尖的技术专家…

Unity坦克大战开发全流程——1)需求分析

实践项目&#xff1a;需求分析 该游戏共有三个主要部分&#xff1a;UI、数据储存、核心游戏逻辑&#xff0c;下面我们将从开始场景、游戏场景、结束场景三个角度切入进行分析。

教练技术中要注意的两点

今天看到2022 china devopsday中陈老师不错的关于教练技术描述的两个注意点的PPT&#xff0c;不错&#xff0c;分享下&#xff1a;

fastjosn利用分析

fastjosn一般是使用TemplatesImpl链来进行攻击的&#xff0c;在上面其实已经分析过fastjson在反序列化的时候会调用满足条件的getter方法&#xff0c;因此就会调用TemplatesImpl类的getOutputProperties方法&#xff0c;然后通过getOutputProperties&#xff0c;调用newTransfo…

Linux权限的基本理解

一:&#x1f6a9;Linux中的用户 1.1&#x1f966;用户的分类 &#x1f31f;在Linux中用户可以被分为两种用户: 超级用户(root):可以在Linux系统中做各种事情而不被约束普通用户:只能做有限的事情被权限约束 在实际操作时超级用户的命令提示符为#,普通用户的命令提示符为$,可…

react+redux+antd-mobile 之 记账本案例

1.环境搭建 //使用CRA创建项目&#xff0c;并安装必要依赖&#xff0c;包括下列基础包 //1. Redux状态管理 - reduxjs/toolkit 、 react-redux //2. 路由 - react-router-dom //3. 时间处理 - dayjs //4. class类名处理 - classnames //5. 移动端组件库 - antd-mobile //6. 请…

论文阅读——EfficientViT(cvpr2023)

EfficientViT: Memory Efficient Vision Transformer with Cascaded Group Attention 1、 从三个角度探讨如何提高vision transformers的效率&#xff1a;内存访问、计算冗余和参数使用。 2.1. Memory Efficiency 红色字体表示操作所花费的时间主要由内存访问决定&#xff0c;…

DHCP学习记录

目录 客户端向DHCP服务端申请租用IP的4个阶段: 客户端向HDCP服务器续租IP过程: 客户端重新连接租用IP过程: 客户端释放IP 声明: (Dynamic Host Configuration Protocol)动态主机配置协议&#xff0c;客户端向DHCP服务端申请获得ip的一种约定俗成的话语(协议) 手工配置方式…

Docker单点部署Seata(2.0.0) + Nacos(v2.3.0) + Mysql(5.7)

文章目录 一、部署Nacos二、部署Mysql三、Seata准备工作1. 记住nacos、mysql、宿主机的ip2. 建立数据库3. Nacos远程配置文件 四、部署Seata五、初步检验Seata部署情况六、微服务使用Seata1.引入依赖2. application.yml配置 七、遇到的坑1. Nacos显示Seata服务的ip为容器内网ip…