C 嵌入式系统设计模式 10:中介者模式

本书的原著为:《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》,讲解的是嵌入式系统设计模式,是一本不可多得的好书。

本系列描述我对书中内容的理解。本文章描述访问硬件的设计模式之三:中介者模式。

中介者模式 (Mediator Pattern) 是一种设计模式,它在软件工程中用于减少类与类之间的直接依赖,降低系统的耦合度,使系统更加灵活和可扩展。该模式通过引入一个中介者对象,将原本需要直接交互的多个对象之间的关系转化为中介者与这些对象之间的关系,从而实现了解耦。

在本书中,中介者模式用于协调复杂交互,使得各个硬件接口不需要显示地相互引用,从而降低耦合度。

为了更好地理解中介者模式,我们可以将其比作现实生活中的房屋中介。在房屋租赁市场中,房东和租客之间通常需要直接进行交互以完成租赁交易。然而,当市场变得复杂时,这种直接交互可能会变得困难且效率低下。此时,房屋中介作为中介者出现,他们负责协调房东和租客之间的交互,处理租赁合同、租金支付等事务,从而简化了交互过程。

在软件工程中,中介者模式同样扮演着类似的角色。例如,在一个图形用户界面(GUI)系统中,多个组件(如按钮、文本框等)之间可能需要进行复杂的交互。如果每个组件都直接与其他组件进行交互,那么系统的耦合度将会非常高,一旦某个组件发生变化,可能会影响到其他多个组件。此时,可以引入一个中介者对象(如事件处理器)来管理这些组件之间的交互。当某个组件需要与其他组件进行交互时,它只需将请求发送给中介者对象,由中介者对象负责协调和处理这些请求。

中介者模式的核心在于将原本复杂的对象间关系转化为简单的中介者与对象间的关系。这种转化不仅降低了系统的耦合度,还提高了系统的可维护性和可扩展性。当需要添加新的交互关系或修改现有交互关系时,只需修改中介者对象即可,而无需修改其他多个对象。

然而,中介者模式也存在一些潜在的问题。例如,如果中介者对象变得过于复杂和庞大,那么它可能会成为系统中的瓶颈。此外,如果系统中存在多个中介者对象,它们之间可能需要进行协调和管理,否则可能会导致系统变得混乱和难以维护。

摘要

通过引入一个中介者对象来封装硬件元素之间交互的复杂性,中介者模式允许硬件元素之间更松散的耦合,提高了代码的可维护性和可扩展性。在C语言中,由于没有直接支持面向对象编程的特性,如类和继承,因此使用中介者模式可以避免因过度使用特殊化而导致的实现复杂性增加。相反,中介者模式可以通过结构体和函数指针等C语言特性来实现,从而简化对硬件元素的管理和协调。

问题

许多嵌入式应用控制一组执行器,这些执行器必须协同工作才能实现预期的效果。例如,为了实现多关节机械臂的协调运动,所有电机必须协同工作以提供所需的机械臂运动。类似地,在三维空间中使用航天器的反作用轮或推进器时,需要许多不同的此类设备,它们要在精确的时刻、提供适当的作用力,才能实现姿态稳定。

在这种情况下,中介者模式可以用来管理这些执行器之间的复杂交互。中介者可以作为一个集中的控制点,接收来自应用程序的指令,并根据需要协调各个执行器的行为。这样可以将执行器之间的直接交互降到最低,使得系统更加模块化和可维护。同时,通过使用中介者模式,我们可以更容易地添加、修改或删除执行器,而不需要对整个系统进行大规模的修改。

模式结构

模式结构图如下图所示:
在这里插入图片描述

中介者模式使用一个中介者类来协调一组协作设备的 动作 (actions),以实现所需的整体效果。中介者类协调对多个具体协作者(Specific Collaborator)集合的控制(它们的数量由图3-5中中介者和具体协作者之间的关联上的’*'表示)。当发生感兴趣的事件时,每个具体协作者必须能够联系中介者。

在这种模式中,中介者充当了中央控制器的角色,负责接收和处理来自各个协作者的消息,并根据需要协调它们的行为。这样可以将协作者之间的直接依赖关系降到最低,提高了系统的可维护性和可扩展性。同时,由于中介者负责协调和控制整个系统的行为,因此可以更容易地实现复杂的交互和协作逻辑。

模式详情

协作者接口

协作者接口(Collaborator Interface)是所有具体协作者共有的一组服务的规范,这些服务可以被中介者调用。例如,对于所有硬件设备来说,通常会有 initialize() 、reset()、shutdown() 等操作,以便将它们都带到一个已知的初始状态、恢复状态、关闭状态。每个通用服务必须在每个具体协作者中实现(当然,实现通常对每个协作者来说是唯一的)。

通过使用协作者接口,我们可以确保中介者能够与所有具体协作者以一致的方式进行交互,而无需关心它们的具体实现细节。这有助于降低系统的复杂性,并提高代码的可维护性和可扩展性。同时,这也为添加新的具体协作者提供了灵活性,因为只要它们实现了协作者接口,就可以与中介者进行交互。

具体协作者

具体协作者(Specific Collaborator)代表一个设备,因此可能是一个设备驱动程序或硬件代理。它接收中介者的命令消息,并在发生感兴趣的事件时向中介者发送消息。

在中介者模式中,具体协作者通常负责处理与具体设备相关的具体操作和事件。它们与中介者进行交互,通过接收中介者的命令来执行相应的操作,并在必要时向中介者发送事件消息以通知其状态变化或其他重要事件的发生。

通过将设备逻辑封装在具体协作者中,中介者模式实现了设备与系统其他部分之间的解耦。这使得系统更加模块化,易于维护和扩展。同时,具体协作者的设计也使得对设备的控制和管理更加集中和统一,提高了系统的整体效率和可靠性。

中介者

中介者 类(Mediator)在模式中协调 具体协作者 。它与每个具体协作者都有关联,以便可以向其发送消息。此外,当发生感兴趣的事件时,每个具体协作者必须能够向中介者发送消息。中介者提供了协调逻辑,避免了具体协作者之间相互协调。

通过引入中介者,我们可以将原本分散在具体协作者之间的交互和依赖关系集中到中介者身上,从而降低了系统的复杂性。中介者负责管理和维护具体协作者之间的关系,确保它们按照预定的规则和顺序进行交互。这样,具体协作者之间不再需要直接相互引用和调用,而是通过中介者来进行间接的交互,提高了系统的灵活性和可维护性。

同时,中介者模式也使得我们可以更容易地添加、删除或替换具体协作者,而不需要对整个系统进行大规模的修改。因为中介者封装了与具体协作者的交互逻辑,所以当我们需要改变某个具体协作者的行为时,只需要修改中介者与该协作者的交互逻辑即可,而不需要修改其他具体协作者或整个系统的代码。这大大提高了系统的可扩展性和可维护性。

效果

此模式创建了一个中介者,用于协调一组协作执行器,但不需要这些设备之间的直接耦合。通过最小化耦合点并将协调逻辑封装在单个元素内,这大大简化了整体设计。每当协作者需要联系另一个协作者时,它会通知中介者,中介者可以决定如何作为一个整体的协作体进行响应。

由于许多嵌入式系统必须实时控制,因此动作之间的延迟可能会导致不稳定或不良的影响。中介者类能够在这些时间限制内作出反应是非常重要的。当执行器与中介者之间存在双向协作时,这一点尤其令人关注。

实现策略

中介者必须能够与每个具体协作者建立关联。这可以通过指针数组、为每个具体协作者设置单独的指针,或者将两者组合起来实现。一个常见的经验法则是,如果一组具体协作者具有相同的行为(例如,它们遵循一个通用接口),那么指针数组是最佳选择。如果具体协作者有不同的用途,则为每个这样的具体协作者使用单独的链接。

甚至可以将不同的具体协作者分组,其中组内的每个类都提供一个通用接口。这样,中介者可以更容易地管理和协调具有相似功能或特性的协作者集合。

相关模式

此模式与经典《设计模式》书籍中的策略模式相似。在这种情况下,我们关注其在详细硬件协调方面的应用。

策略模式通常用于定义一系列的算法,并将每一个算法封装起来,使它们可以互相替换。策略模式使得算法可以独立于使用它的客户端变化。而在中介者模式中,我们同样看到了一种将行为或策略封装在中介者中的做法,这使得具体协作者之间的交互可以被中介者管理和协调。

在某些情况下,可以用观察者模式代替中介者模式。观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。在中介者模式中,如果具体协作者需要与多个其他对象进行交互,或者我们不希望具体协作者直接知道中介者的存在,那么可以使用观察者模式来实现这种间接的交互。

实例

见原书

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

hash,以及数据结构——map容器

1.hash是什么? 定义:hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出, 该输出就是散列值。这种转换是一种压缩映射&…

谷歌浏览器文件下载不了的问题

问题: 谷歌浏览器测试环境a标签下载附件没问题,但是另一个环境下载闪了一下但是没有下载. 原因:测试环境http,附件下载链接是http,但是另一个环境网页地址是https,附件下载链接是http. Chrome将开始阻止“安全页面”(HTTPS)上所有“非安全子资源”&#…

BeikeShop跨境电商PHP商城源码

BeikeShop 一款开源好用的跨境电商系统,BeikeShop 是基于 Laravel 开发的一款开源商城系统主要面向外贸/跨境电商行业提供商品管理、订单管理、会员管理、支付、物流、系统管理等功能。 插件市场支持个人免签 BeikeShop系统亮点 1、系统代码100%开源 2、代码分层…

RabbitMQ开启MQTT协议支持

1)RabbitMQ启用MQTT插件 rootmq:/# rabbitmq-plugins enable rabbitmq_mqtt Enabling plugins on node rabbitmq: rabbitmq_mqtt The following plugins have been configured:rabbitmq_managementrabbitmq_management_agentrabbitmq_mqttrabbitmq_web_dispatch Ap…

Linux理解

VMware安装Linux安装 目录 VMware安装Linux安装 1.1 什么是Linux 1.2 为什么要学Linux 1.3 学完Linux能干什么 2.1 主流操作系统 2.2 Linux系统版本 VMware安装Linux安装 1.1 什么是Linux Linux是一套免费使用和自由传播的操作系统。 1.2 为什么要学Linux 1). 企业用人…

unity Aaimation Rigging使用多个约束导致部分约束失去作用

在应用多个约束时,在Hierarchy的顺序可能会影响最终的效果。例如先应用了Aim Constraint,然后再应用Two Bone Constraint,可能会导致Two Bone Constraint受到Aim Constraint的影响而失效。因此,在使用多个约束时,应该仔…

【Java程序设计】【C00293】基于Springboot的藏区特产销售平台(有论文)

基于Springboot的藏区特产销售平台(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的藏区特产销售平台 本系统分为系统功能模块以及管理员功能模块。 系统功能模块:进入藏区特产销售平台页面中可以查看…

【Git】:远程仓库操作

远程仓库操作 一.理解版本控制系统二.远程仓库1.克隆2.Push操作3.fetch操作4. .gitnore文件 一.理解版本控制系统 我们⽬前所说的所有内容(⼯作区,暂存区,版本库等等),都是在本地!也就是在你的笔记本或者计…

前端输入框校验限制不能输入中文

一般我们在做表单的时候都会有表单校验,通常都是用element提供的表单验证的功能,只需要通过 rules 属性传入约定的验证规则,如下面这样 rules: {userName: [{validator: checkUsername,trigger: "blur",},{ validator: this.checkData, trigge…

navicat导出数据库表结构信息

需求阐述 要求导出某一数据库表中的所有表的结构,汇总成一个word 准备工作 拿到所有表名,在navicat中执行sql语句:show tables;然后点击导出结果,选择excel格式进行导出。 拿到该数据库所有表名后,在navicat中执行如…

动态SLAM:基于ORB-SLAM2与YOLOv8剔除动态特征点(三种方法)

基于ORB-SLAM2与YOLOv8剔除动态特征点(三种方法) 写上篇文章时测试过程比较乱,写的时候有些地方有点失误,所以重新写了这篇 本文内容均在RGB-D环境下进行程序测试 本文涉及到的动态特征点剔除速度均是以https://cvg.cit.tum.de/data/datasets/rgbd-dat…

SpringCloud(15)之SpringCloud Gateway

一、Spring Cloud Gateway介绍 Spring Cloud Gateway 是Spring Cloud团队的一个全新项目,基于Spring 5.0、SpringBoot2.0、 Project Reactor 等技术开发的网关。旨在为微服务架构提供一种简单有效统一的API路由管理方式。 Spring Cloud Gateway 作为SpringCloud生态…

WebService学习,wsdl文件详解

目录 第一章、起因1.1)学习原因1.2)提问的过程(逐步提出问题)1、?wsdl链接的含义,有什么作用?2、什么是wsdl文档?3、如何阅读wsdl文件?4、wsdl文件有什么作用&#xff1f…

【校招】从容面对笔试面试

笔试面试经验分享 一、笔试二、面试1.自我介绍2. 技术面试 一、笔试 如果是面试研发岗的话一般都是有笔试,难度因公司而异,一般来说越大的公司笔试就越难。对于不同岗位考察的方向也不一样,比如如果岗位是偏通信类的话多一点的话可能就会考一…

【Vuforia+Unity】AR03-圆柱体物体识别(Cylinder Targets)

1.创建数据库模型 这个是让我们把生活中类似圆柱体和圆锥体的物体进行AR识别所选择的模型 Bottom Diameter:底部直径 Top Diameter:顶部直径 Side Length:圆柱侧面长度 请注意,您不必上传所有三个部分的图片,但您需要先为侧面曲面关联一个图像&#…

探索无限:Sora与AI视频模型的技术革命 - 开创未来视觉艺术的新篇章

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua,在这里我会分享我的知识和经验。&#x…

同一个包下 golang run时报undefined

问题描述 今天在运行一个项目,一个包下有两个文件,分别是main.go和route,main函数在main.go文件中,main引用了route.go中的两个函数,SetupRoutes和SetupAdminRoutes go build 编译后,直接运行&#xff0c…

算法——模拟

1. 什么是模拟算法? 官方一点来说 模拟算法(Simulation Algorithm)是一种通过模拟现实或抽象系统的运行过程来研究、分析或解决问题的方法。它通常涉及创建一个模型,模拟系统中的各种事件和过程,以便观察系统的行为&a…

pclpy 可视化点云(多窗口可视化、单窗口多点云可视化)

pclpy 可视化点云(多窗口可视化、单窗口多点云可视化) 一、算法原理二、代码三、结果1.多窗口可视化结果2.单窗口多点云可视化 四、相关数据五、问题与解决方案1.问题2.解决 一、算法原理 原理看一下代码写的很仔细的。。目前在同一个窗口最多建立2个窗…

PCIE转USB3.0方案(VL805,VL806)

VLI VL806 是一款单芯片 USB 3.0 主机控制器,可使配备 PCI Express 的平台能够具有 USB 超高速 (5 Gbps)、高速 (480 Mbps)、全速 (12 Mbps) 和低速 (1.5 Mbps) 设备。根…