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

news2024/9/20 10:42:54

本书的原著为:《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://www.coloradmin.cn/o/1465051.html

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

相关文章

https://registry.npm.taobao.org淘宝npm镜像仓库地址更新

在工作中有遇见获取淘宝的npm镜像存在问题,图示如下的报错: 根据报错的内容是说 https://registry.npm.taobao.org地址访问失败了,然后通过排查发现淘宝的npm镜像仓库地址有更新了。需要使用最新的地址 旧的淘宝镜像仓库:https://…

如何进行高性能架构的设计

一、前端优化 减少请求次数页面静态化边缘计算 增加缓存控制:请求头 减少图像请求次数:多张图片变成 一张。 减少脚本的请求次数:css和js压缩,将多个文件压缩成一个文件。 二、页面静态化 三、边缘计算 后端优化 从三个方面进…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的鸟类识别系统(Python+PySide6界面+训练代码)

摘要:本文详细阐述了一个利用深度学习进行鸟类识别的系统,该系统集成了最新的YOLOv8算法,并与YOLOv7、YOLOv6、YOLOv5等先前版本进行了性能比较。该系统能够在图像、视频、实时视频流和批量文件中精确地识别和分类鸟类。文中不仅深入讲解了YO…

10.Halcon形态学膨胀,腐蚀,开运算,闭运算

膨胀:对边界点进行扩充,填充空洞,使边界向外部扩张的过程。 腐蚀:消除物体边界点,使边界向内部收缩的过程,把小于结构元素的物体去除掉. 开运算: 先腐蚀后膨胀的过程称为开运算。 作用 : 去除孤立的小点,毛刺,消除小物体,平滑较大物体边界,同时不改变其面积. 闭运…

用友U8库存展望数据显示错误

1、库存展望显示有订单在途。 2、双击查看明细,显示某个采购订单显示有预计入库量。 3、查询该采购订单,发现已入库完成未退货,确定为数据异常。 修改采购订单表体的iReceivedQTY(累计到货数量)字段后,恢复正常。 UPDATE dbo.PO_…

koa项目部署云服务器(部署本地虚拟机中)

文章目录 一、服务器安装Node、MySQL1.1. 安装Node.js1.2. 安装MySQL1.3.配置MySQL1.4. 数据库迁移 二. 部署Node项目2.1. 代码托管到Git仓库(选做)2.2. 代码clone到服务器(选做)2.3. VSCode中打开代码(推荐&#xff0…

A股风格因子看板 (2024.2 第08期)

该因子看板跟踪A股风格因子,该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子,用以分析市场风格切换、组合风格景 露等。 今日为该因子跟踪第8期,指数组合数据截止日2024-01-31,要点如下 近1年A股风格因子收益走…

Android约束布局中用ConstraintHelper实现过渡动画效果

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂,风趣幽默",感觉非常有意思,忍不住分享一下给大家。 👉点击跳转到教程 一.创建一个类CircularRevealHelper继承ConstraintHelper代码如下 /*** Author: ly* Da…

机器学习基础(二)监督与非监督学习

导语:更深入地探讨监督学习和非监督学习的知识,重点关注它们的理论基础、常用算法及实际应用场景。 上一节我们深入探索机器学习的根本原理,包括基本概念、分类及如何通过构建预测模型来应用这些理论,详情可见: 机器学…

centos中安装go

安装过程 (1)源码二进制下载地址 wget https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz (2)将下载的二进制包解压至 /usr/local目录。 tar -C /usr/local/ -xzf go1.13.5.src.tar.gz (3)设置环…

自定义电子凸轮曲线的运动:EtherCAT超高速实时运动控制卡XPCIE1032H上位机C#开发(十三)

PCIE1032H功能简介 XPCIE1032H是一款基于PCI Express的EtherCAT总线运动控制卡,可选6-64轴运动控制,支持多路高速数字输入输出,可轻松实现多轴同步控制和高速数据传输。 XPCIE1032H集成了强大的运动控制功能,结合MotionRT7运动控…

week04day03(爬虫 beautifulsoup4、)

一. 使用bs4解析网页 下载bs4 - pip install beautifulsoup4 使用的时候 import bs4专门用于解析网页的第三方库 在使用bs4的时候往往会依赖另一个库lxml pip install lxml 网页代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><…

使用redisMQ-spring-boot-starter实现消息队列和延时队列

简介 redisMQ-spring-boot-starter是一个轻量级的、基于Redis实现的消息队列中间件&#xff0c;它有如下优点&#xff1a; 开箱即用&#xff0c;你几乎不用添加额外的配置支持消息队列、延时队列&#xff0c;并提供精细化配置参数提供消息确认机制支持虚拟空间&#xff0c;不…

华为算法题 go语言或者ptython

1 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的景区垃圾识别系统(Python+PySide6界面+训练代码)

摘要&#xff1a;本文介绍了一个先进的基于深度学习的景区垃圾检测系统&#xff0c;该系统集成了最新的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5等前代算法进行了性能对比&#xff0c;通过对比实验证明了其在图像、视频、实时视频流和批量文件处理中对景区垃圾进行精…

【深度学习笔记】3_1 线性回归

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 3.1 线性回归 线性回归输出是一个连续值&#xff0c;因此适用于回归问题。回归问题在实际中很常见&#xff0c;如预测房屋价格、气温、销售额等连续值的问题。与回归问…

HTTP基本概念-HTTP 常见的状态码有哪些?

资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) HTTP 常见的状态码有哪些? 1xx 类状态码属于提示信息&#xff0c;是协议处理中的一种中间状态&#xff0c;实际用到的比较少。 2xx 类状态码表示服务器成功处理了客户端的请求&#xff0c;也是我们最愿…

数据库事物复习

事务 比如说将张三的银行账户拿出一千给李四&#xff0c;首先需要查询张三的账户余额&#xff0c;扣除1000&#xff0c;然后如果给李四加上1000的过程中出现异常会回滚事务&#xff0c;临时修改的数据会回复回去。 -- 1. 查询张三账户余额 select * from account where name …

OpenAI Sora模型,官方技术文档翻译

技术报告地址&#xff1a;https://openai.com/research/video-generation-models-as-world-simulators 本技术报告的重点是&#xff08;1&#xff09;将所有类型的视觉数据转化为统一表示&#xff0c;从而能够大规模训练生成模型的方法&#xff1b;以及&#xff08;2&#xff0…

互联网广告投放与IP地理位置定位

随着互联网的发展和普及&#xff0c;互联网广告投放成为各行业推广营销的重要方式之一。而结合IP地理位置定位技术&#xff0c;可以实现精准定向&#xff0c;提高广告投放的效果和精准度。IP数据云将探讨互联网广告投放与IP地理位置定位的关系&#xff0c;分析其优势和应用场景…