0%

【编程】嵌入式单片机C语言开发之设计模式概述

前言

刚入职时就听导师谈起设计模式,也被建议去看《设计模式》这本书,当时只觉高深莫测,兴冲冲地去买了书籍回来打算在工作之余细细研读一番,脑海里还臆想着通读完此书即可功力大成

只可惜,作为一名嵌入式C语言开发小白,根本看不懂用 Java语言 写的《设计模式》,硬着头皮读了几天书也就弃下了。眼瞅着看书这条路径走不通,当然要换种思路了,总要跟设计模式扯上点关系不是?

于是,又去网上搜罗拜读了一堆适宜小白阅览的文章,想着如何给私有的C业务代码应用上各种设计模式,好展示一番代码功底

后来,在知乎看到了一条评论:“往往都是那些毕业一两年的小白楞头青,才会整天想着设计模式如此如此,非得本末倒置地给业务强行用上各种设计模式,仿佛只有这样才能满足其那颗躁动的心”。受此评论触动,深觉业务开发才是技术之本,应当去多研读工程业务之源码,没必要硬磕设计模式,当所了解与所开发的业务越来越繁杂的时候,那么设计模式及其相关思想的应用落地也就是必然的事情了。


现如今,已工作一年有余,也接触开发了不少项目,个中也有较多业务逻辑用到设计模式的思想,因此有必要系统回顾并总结一下在嵌入式开发中所应用到的设计模式

设计模式概述

本章节阐述本人对设计模式浅薄的书面理解。

首先,我们需要理清设计思想设计模式这两个概念:

通常我们会说,进行软件设计,最重要的是思想,对于一个嵌入式软件工程师来说,首要的就是设计思想。当一个项目交到手上,我们会想这个工程能不能实现、其功能业务理论可行性,而探讨可行性,即是在构思软件的大致解决思路和方法,这就是软件顶层思想的具体实践了。而在正式开展编码工作之前,当然要明确下代码的架构设计,比如:如何对业务进行划分具体模块、如何对整体工程划分层次、如何设计交互接口等等,这些都是属于设计思想的范畴。

当然,只有设计理论,没有编码设计实践是万万不行的。而设计模式即是设计思想的具体实践,我们说想要在代码上应用到我们的思想,最好是不要闭门造车,要多参考他人的代码设计方法,如设计模式,其是前人基于设计思想提炼出来的经过无数验证的成熟模型。参考使用设计模式可以帮助更好地组织代码、提高可维护性、保证软件的可靠性。

以上纯属废话,鄙人对设计模式其实也没明确的概念,也不建议事事都要扯上设计模式,私以为如果一个软件模块的可读性良好、逻辑层次清晰明了、方便进行扩展设计和维护、能够很好地实现目标业务功能,那么其即属于优秀的软件设计。

实际开发应用分析

未完待续。。。。。。

状态模式及其应用分析

状态机广泛应用于嵌入式业务开发中

  • 设备状态机:整机设备在其工作周期中存在不同的状态,每个状态下接收到不同的事件,会有不同的响应操作,此时在整个设备顶层业务开发中可以应用状态模式。
  • 通信协议封包、解包设计:解包时,可以定义当前对 缓存数据 的解包状态,如获取到起始位、包头解析、数据解析、包校验等等、通过状态机设计,可以实现高效严谨通用的解包库函数设计。
  • 通信协议应用业务:在通信协议处理中,也存在状态的切换和不同状态下的处理回复,比如握手、握手回复、获取相关信息、等等,可以应用状态模式来设计 设备间通信协议的交互。

当然模块内业务根据需要也可以应用状态模式,在不同的状态下接收到不同的事件,从而执行相应的操作

观察者模式及其应用分析

观察者模式:

如:在按键示例中,按键事件可以当作被观察者,受按键触发的其它操作为观察者,当轮询检测到按键按下时,调用所有观察者回调函数

如:温度监控

如:状态变化

命令模式及其应用分析

命令模式,通俗点理解就是通过一层转换,将输入的命令码对应成相应的执行操作。(ps:有大神说该模式的核心在于把命令下达与命令执行在时间上进行分离

一个代码实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
struct tiny_ev_map_func
{
uint16_t cmd;
void (*func)(void);
};

static const struct tiny_ev_map_func main_ev_func_list[] =
{
{MAIN_EV_CHARGER_INSERT, func_ev_pm_charge_insert},
{MAIN_EV_CHARGER_FINISH, func_ev_pm_charge_finish},
{MAIN_EV_BAT_ELE_QUANTITY, func_ev_pm_ele_quantity},
{MAIN_EV_BAT_TEMPERATURE, func_ev_pm_temperture},
{MAIN_EV_BAT_TEMP_ABNORMAL, func_ev_pm_temp_abnormal},
{MAIN_EV_BTN_FIRST, func_ev_btn_first},
{MAIN_EV_BTN_SECOND, func_ev_btn_second},
{MAIN_EV_HEATER_COMPLEX, func_ev_heater_complex},
{MAIN_EV_HEATER_SWITCH, func_ev_heater_switch},
{MAIN_EV_HEATER_TEMP_USER, func_ev_heater_temp_user},
{MAIN_EV_HEATER_TEMP_RT, func_ev_heater_temp_rt},
{MAIN_EV_HEATER_ERROR, func_ev_heater_error},
{MAIN_EV_MASSAGE_EV_SWITCH, func_ev_massage_switch},
{MAIN_EV_MASSAGE_EV_MODE, func_ev_massage_mode},
{MAIN_EV_MASSAGE_EV_ERROR, func_ev_massage_error},
}

void module_func_map_cmd(uint16_t cmd)
{
for (int i = 0; i < ARRAY_SIZE(main_ev_func_list); ++i)
if (main_ev_func_list[i].cmd == cmd)
main_ev_func_list[i].func();
}

适配器模式及其应用分析

用于将一个接口转换成另一个接口,从而实现更好的模块层级间调用、接口兼容、解耦

用于不同硬件设备的兼容、不同软件模块的兼容等

外观模式及其应用分析

外观模式用于隐藏一系列复杂接口,为外部或者上层应用提供一个统一简单的接口,使得开发者无须关心其内复杂的实现,并可降低代码耦合度

如 RT-Thread 设备驱动框架:

  • I/O 设备管理层:应用程序通过 I/O 设备提供的标准接口访问底层设备,使得设备驱动的升级和迭代不会对上层应用产生影响
  • 设备驱动框架层:抽象同类硬件设备驱动,如 ADC、PWM、UART等分类
  • 设备驱动层:驱使硬件设备工作的底层程序

中介者模式及其应用分析

该模式通过引入一个中介者对象,将原本需要直接交互的多个对象之间的关系转化为中介者与这些对象之间的关系,从而实现了解耦。

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

访问者模式及其应用分析

较为复杂,暂未理解,后续补充

示例代码实现

此处略,后续文章补充

参考站点