汇总:嵌入式软件框架设计常用模式
扫描二维码
随时随地手机看文章
嵌入式软件因为硬件资源限制,可能存在驱动与应用耦合的情况,但对于大型项目,资源充裕的情况下,复杂的业务逻辑、后续扩展维护的需要,必须采用分层和模块化思维,这种思想就是架构模式。一般分7种架构模式:
① 分层架构
② 多层架构
③ 管道 - 过滤器架构
④ 客户端 - 服务器架构
⑤ 模型 - 视图 - 控制器架构
⑥ 事件驱动架构
⑦ 微服务架构
其中加粗部分属于个人觉得适合在嵌入式系统应用的架构(模式),实际开发中一般是多种模式嵌套,确保软件隔离解耦。
一、分层架构模式
最常见的架构模式就是分层架构,大部分分层架构主要由四层组成:展现层、业务层、持久层和数据库层,如下图所示:
1、上下文
复杂的系统都会经历独立的发展和衍化系统各个部分的需要。出于这个原因,系统开发者需要对关注点进行清晰且条理分明的分离,以便系统的各个模块可以独立地开发和维护。
2、问题
软件需要以这样一种方式分割:各个模块可以独自开发和衍化,各自部分之间的交互非常少,支持可移植性、可修改性和复用性。
3、方案
为了实现关注点分离,分层模式将软件分割成各个单元(称为“层”)。每一层都是一组模块,提供了一组高内聚的服务。其使用必须是单向的。层将一组软件作为一个完整的分区,每个分区暴露一个公开接口。
✪ 第一个概念是,每一层都有特定的角色和职责。例如,展现层负责处理所有的用户界面。分层架构的这种关注点分离,让构建高效的角色和职责非常简单。
✪ 第二个概念是,分层架构模式是一个技术性的分区架构,而非一个领域性的分区架构。它们是由组件组成的,而不是领域。
✪ 最后一个概念是,分层架构中的每一层都被标记为封闭或者开放。封闭层意味着请求从一层移到另一层,它必须通过它正下面的这一层才能达到下面这一层的再下一层。请求不能跳过任何层。
4、弱点
分层会导致性能下降。这种模式不适合高性能应用程序,因为经过架构中的多层来实现一个业务请求的效率是不高的。还会增加系统的前期成本和复杂性。
5、用途
我们应该将这种方式应用于小型简单的应用程序。
点评
原文是针对互联网软件,对于嵌入式可以分为业务层、公共组件层、系统适配层、硬件驱动层。软件分层思想是个基础概念,也许在嵌入式软件中体现不明显,是因为硬件资源限制有所取舍。
二、多层模式
方案:
许多系统的执行结构被组织成一系列逻辑组件分组。每个分组被称为一个层。
1、上下文
在一个分布式部署中,通常需要将系统的基础设施分到不同的子集中。
2、问题
我们如何将系统分割到多个计算上独立的执行结构:由一些通信媒介连接的软件和硬件组?
3、弱点
大量前期成本和复杂性。
4、用途
用在分布式系统中。
点评
个人能力限制,暂不明白在嵌入式软件中的用法和使用范围。
三、管道-过滤器架构
软件架构中反复出现的一种模式是管道 - 过滤器(pipe-filter)模式。
1、上下文
许多系统需要转换从输入到输出的离散数据流。许多类型转换在实践中重复出现,因此将其创建成独立的可复用的部分,这是比较理想的。
2、问题
这些系统需要被分割成可复用的松耦合的组件,组件之间拥有简单通用的交互机制。这样它们就可以灵活地相互结合。这些通用松耦合的组件就很容易复用。独立的组件可以并行执行。
3、方案
这种架构中的管道构成了过滤器之间的通信通道。第一个概念是,由于性能原因,每个管道都是非定向的和点对点的,接受来自一个源的输入并经常直接输出到另外一个源。
在这种模式中,有如下四种过滤器。
✪ producer(source):一个过程的起点。
✪ transformer (map):对一些或所有数据进行转换。
✪ tester (reduce):测试一个或多个条件。
✪ consumer (sink):终点。
4、弱点
不太适合交互性的系统,因为它们的转换特性。
过多的解析和反解析会导致性能损失,也会增加编写过滤器本身的复杂性。
5、用途
管道 - 过滤器架构用于各种应用程序,特别是简化单项处理的任务。
点评
看起来比较类似广播与接收的模式,在无操作系统消息队列机制,基于单片机裸机开发时可以使用,所有分时任务共享一个广播队列,接收时选择自身感兴趣的进行处理,或者对广播消息进行删除截断后续操作。
四、客户端-过滤器架构
1、上下文
有许多共享资源和服务是大量分布式的客户端希望访问的,希望控制访问或服务质量。
2、问题
通过管理一组共享资源和服务,我们可以通过分解公共服务并在单个位置或少数位置进行修改来提高可修改性和复用性。我们想要通过在将资源本身分布在多个物理服务器上的同时集中控制这些资源和服务,来提高可伸缩性和可用性。
3、方案
在客户端 - 服务器模式中,组件和连接器具有特定的行为。
称为“客户端”的组件将请求发送到称为“服务器”的组件,然后等待回复。
服务器组件接收到客户端的请求并向其发送回复。
4、弱点
服务器会成为性能瓶颈和单点故障位置。在系统建成后,关于功能位置(在客户端还是在服务器)的决策通常是复杂的而且变动成本很大。
5、用途
对于有许多组件(客户端)发送请求到另外一些提供服务的组件(服务器)的系统,我们可以使用客户端 - 服务器模式来建模这个系统的一部分:在线应用程序,例如电子邮件、共享文档或银行服务。
点评
这个好像只适合互联网软件。
五、模型-视图-控制器架构(MVC)
1、上下文
用户界面通常是一个交互性应用程序的最频繁被修改的部分。用户通常希望从不同的视角查看数据,例如柱状图或者饼图。这些表示形式都应该反映数据当前的状态。
2、问题
用户界面功能如何独立于应用程序功能,同时还还对用户输入或底层应用程序数据的更改做出响应?
当底层应用程序数据更改时,如何创建、维护和协调用户界面的多个视图?
3、方案
模型 - 视图 - 控制器(model-view-controller,即 MVC)模式将应用程序功能分为以下三种类型的组件:
✪ 模型,包含应用程序的数据。
✪ 视图,显示部分底层数据并与用户交互。
✪ 控制器,在模型和视图之间进行中介并管理状态更改的通知。
4、弱点
对于简单的用户界面,其复杂性并不值得这么做。
模型、视图和控制器抽象可能不适用于某些用户界面工具包。
5、用途
MVC 是网站或移动应用程序开发用户界面常用的一种架构模式。
点评
这模式一般用在支持显示的场景,底层对数据的维护管理,与界面显示分离,这样当业务需求、显示部分变更对底层基础影响较小,似乎是软件分层模式的特例。
六、事件驱动架构
1、上下文
需要提供计算和信息资源来处理传入的应用程序生成的独立异步事件,这种方式可以随着需求的增加而扩展。
2、问题
构建分布式系统,这个系统可以服务异步到达的事件相关信息,并且能从简单小型扩展到复杂大型。
3、方案
为事件处理部署独立的事件进程或处理器。到达的事件进入队列。调度程序根据调度策略从队列中拉取事件并将它们分配到合适的事件处理器。
4、弱点
性能和错误恢复可能是问题。
5、用途
使用这个方案的电商应用程序将工作如下:
Order Service 创建一个 Order,这个订单处于待定状态,然后发布一个OrderCreated事件。
✪ Customer Service 接收到这个事件并尝试为这个 Order 扣除信用。然后发布一个 Credit Reserved 事件或者CreditLimitExceeded(超出信用限额)事件。
✪ Order Service 接收到 Customer Service 发送的事件并将订单状态更改为已核准或已取消。
点评
这个在嵌入式软件很容易理解,所谓事件就是硬件检测到中断信息。嵌入式软件基本都有体现这个思想,一个while死循环,等待事件触发,比如外部按键中断、串口接收中断、或者内部定时器超时中断等。这种框架有益于外设扩展,理论上互不干扰。
七、微服务架构
1、上下文
部署基于服务器的企业应用程序,支持各种浏览器和原生移动客户端。应用程序通过执行业务逻辑、访问数据库、与其它系统交换信息并返回响应来处理客户端请求。这个应用程序可能会暴露一个第三方 API。
2、问题
一体化应用程序会变得过于庞大和复杂,无法得到有效支持和部署来实现最优的分布式资源利用,例如在云环境中。
3、方案
将应用程序构建成服务套件。每个服务都是独立部署和可扩展的,拥有自己的 API 边界。不同的服务可以用不同的编程语言编写,管理它们自己的数据库,由不同的团队开发。
4、弱点
系统设计必须能容忍服务失败,需要更多的系统监控。服务编排和事件协作开销比较大。
5、用途
许多使用场景都可以应用微服务架构,特别是那些涉及大量数据管道的场景。例如,一个微服务系统对关于一个公司的零售店销售的报表系统会比较理想。数据展现过程的每一步都会被一个微服务处理:数据收集、清理、规范化、浓缩、聚合、报告等。
点评
在嵌入式软件开发中,比较适合某个相对独立的功能,在适配其基础接口后,将一个复杂功能模块化,外部输入参数,模块内部执行,结束后输出结果或者触发回调,该功能对外接口简单,外部无需过多关注内部实现,便于软件解耦和维护。(转自嵌入式系统)
框架设计中的常用模式
模板方法模式
模板方法模式是框架中最常用的设计模式。其根本的思维是将算法由框架固定,而将算法中详细的操作交给二次开发者达到。例如一个设备初始化的逻辑,框架代码如下:
DownloadFPGA和InitKeyPad都是CBaseDevice定义的虚函数,二次开发者创建一个继承于CBaseDevice的子类,详细来达到这两个接口。框架定义了调用的次序和错误的处理方式,二次开发者没须关怀,也没权决定。
文章相对比较长,字数比较多,大家可以先打开头像关注我,之后慢慢看,///插播一条:我自己在今年年初录制了一套还比较系统的入门单片机教程,想要的同学找我拿就行了免費的,私信我就可以哦~点我头像左下角黑色字体加我也能领取哦。最近比较闲,带做毕设,带学生参加省级或以上比赛///
创建型模式
由于框架通常都波及到各种不同子类对象的创建,创建型模式是经常运用的。例如一个绘图软件的框架,有一个基类定义了图形对象的接口,基于它能够派生出椭圆,矩形,直线各种子类。当用户绘制一个图形时,框架就要实例化该子类。这时候能够用工厂方法,原型方法等等。
音讯订阅模式
音讯订阅模式是最常用的别离数据和界面的方式。界面开发者只须要注册须要的数据,当数据变化时框架就会将数据“推”到界面。界面开发者能够没须关注数据的来源和内部组织形式。
音讯订阅模式最常见的问题是同步模式下怎么样处理重入和超时。作为框架设计者,一定要考虑好这个问题。所谓重入,是二次开发者在音讯的回调函数中执行订阅/取消订阅的操作,这会破坏音讯订阅的机制。所谓超时是指二次开发者的音讯回调函数处理时长过长,导致其他音讯没法响应。最简略的办法是运用异步模式,让订阅者和数据发布者在独立进程/线程中运行。假如不具备此条件,则必需作为框架的重要约定,禁二次开发者产生此类问题。
装饰器模式
装饰器模式赋予了框架在后期增加功能的才能。框架定义装饰器的抽象基类,而由详细的达到者达到,动态地添加到框架中。
举一个游戏中的例子,图形绘制引擎是一个独立的模块,假如能够绘制人物的静止,跑动等图像。假如策划决定在游戏中增加一种叫“隐身衣”的道具,要求穿着此道具的玩家在屏幕上显示的是若有若没的半透明图像。应该怎么样设计图像引擎来适应后期的游戏升级呢?
当隐身衣被装备后,就向图像引擎添加一个过滤器。这是个极度简化的例子,现实中的游戏引擎要比这个复杂。装饰器模式还常见用于数据的前置和后置处理上。
框架的缺少点
一个好的框架能够大大提高产品的开发效率和质量,但也有它的缺少点。
1.框架一般都比较复杂,设计和达到一个好的框架须要相当的时长。所以,一般独有在框架能够被屡次反复应用的时候合适,这时候,前提投入的老本会得到丰厚的回报。
2.框架规定了一系列的接口和规则,这虽然简化了二次开发工作,但同时也要求二次开发者必需记住很多规定,假如违反了这些规定,就不能正常工作。但是由于框架屏蔽了大量的领域细节,相对而言,其进修老本还是大大降低了的。
3.框架的升级对已有产品可能会造成严重的影响,导致须要完整的回归测试。对这个问题有两个办法。第一是对框架自身进行严格的测试,有必要建设完善的单元测试库,同时开发示例项目,拿来测试框架的所有功能。第二则是运用静态链接,让已有产品不轻易跟随升级。当然,假如已有产品有较好的回归测试伎俩,就更好。
4.性能损失。由于框架对系统进行了抽象,增加了系统的复杂性。诸如多态这样的伎俩运用也会普遍的降低系统的性能。但是从整体上来看,框架能够保证系统的性能处于一个较高的水平。