C语言实现设计模式—命令模式
文章目录
- C语言设计模式——命令模式
- 传统的实现方式如下:(伪代码)
- 命令模式优化
- UML 用例说明
- 实现流程
- command.h
- command.c
- main
- 总结
C语言设计模式——命令模式
好处:让代码清晰明了,容易添加和删除,易维护。
哪些地方会用到命令模式?(列出几个常见的例子)
1、按键处理,每个按键按下得到一个索引(指的就是命令),一个按键对应一个处理函数。按键处理命令模式
2、协议解析(串口,网口,CAN,等等);以串口为例简单说明一下,比如有如下协议:http类型解析(html,jpg,jpeg…)
帧头 | 命令 | 数据长度 | 数据内容 | 校验 | 帧尾 |
1字节 | 1字节 | 2字节 | n字节 | 2字节 | 1字节 |
命令1:0x01 温度
命令2:0x02 湿度
命令3:0x03 光照强度
传统的实现方式如下:(伪代码)
static uint8_t parse(char *buffer, uint16_t length)
{uint8_t head = buffer[0];uint8_t cmd = buffer[1];uint16_t len = (buffer[2] << 8) | buffer[3];uint16_t crc = CRCCheck(buffer, length - 3);uint8_t tail = buffer[length - 1];if((head != xxx) && (tail != xxx) && (crc != ((buffer[length - 3]) << 8) | buffer[length - 2])){return 0;}switch(cmd){case 0x01:int temperatue = *(int *)&buffer[4];printf("temperatue = %d\n", temperatue);break;case 0x02:int humidity = *(int *)&buffer[4];printf("humidity = %d\n", humidity);break;case 0x03:int illumination= *(int *)&buffer[4];printf("illumination = %d\n", illumination);break;default:printf("parse error\n");break;}return 1;
}
通过这段伪代码可以看出代码结构的一些问题,如果要添加更多的命令,势必需要向switch case语句中加入更多的case语句。使得解析函数越来越臃肿。当然我们可以使用如下方式规避一些问题:(伪代码)
命令模式优化
命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。
缺点:使用命令模式可能会导致某些系统有过多的具体命令类。
使用场景:认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。
UML 用例说明
实现流程
C语言实现的命令模式核心数据结构是命令。发布命令的是invoker,多个invoker将命令封装起来,送到队列里。有一个函数或者线程称为receiver,检查队列里是否有没有处理的命令。由receiver负责调用各个handler。另外一个被经常使用的辅助数据结构是命令码数组,在如果invoker和handler运行于不同的环境,这种做法几乎是必选,如核间通信,内核和应用态通信。命令码作为索引,handler调用函数作为元素,Receiver根据不同的命令码调用handler。
command.h
#ifndef __COMMAND_H
#define __COMMAND_H#include <rtthread.h>
#include "lw_oopc.h"
#include <stdbool.h>typedef struct rz_command_t rz_command_t;typedef struct rz_command_param_def{uint8_t head;uint8_t cmd;uint16_t length;uint8_t* data;
}rz_command_param_t;typedef struct rz_command_package_entry_def{uint8_t cmd;bool (* handle)(rz_command_t * t);
} rz_command_package_entry_t;CLASS(rz_command_t)
{char *name;rz_command_param_t param;bool (*rz_command_parse)(rz_command_t * pobj, int cmd);void (*init)(rz_command_t * pobj);
};void rz_command_obj_init(void);
rz_command_t * rz_command_obj_get(void);
#endif
command.c
#include "Command.h"static rz_command_t rz_command_obj;rz_command_t * rz_command_obj_get(void)
{return (rz_command_t *)&rz_command_obj;
}static bool parse_temperature(rz_command_t * t)
{rt_kprintf("%s\r\n", __FUNCTION__);return true;
}
static bool parse_humidity(rz_command_t * t)
{rt_kprintf("%s\r\n", __FUNCTION__);return true;
}static bool parse_illumination(rz_command_t * t)
{rt_kprintf("%s\r\n", __FUNCTION__);return true;
}static const rz_command_package_entry_t package_items[] =
{{0x01, parse_temperature},{0x02, parse_humidity},{0x03, parse_illumination},{0xFF, NULL},
};bool rz_command_parse(rz_command_t * pobj, int cmd)
{for(uint8_t i = 0; i < sizeof(package_items)/sizeof(package_items[0]); i++){if((cmd == package_items[i].cmd) && (NULL != package_items[i].handle)){ if(true == package_items[i].handle(pobj)){return true;}}}return false;
}static void command_init(rz_command_t *t)
{t->name = "Command";}void rz_command_obj_init(void)
{rz_command_t * polt = rz_command_obj_get();rz_command_t_ctor(polt);polt->init(polt);
}
CTOR(rz_command_t)
FUNCTION_SETTING(rz_command_parse, rz_command_parse);
FUNCTION_SETTING(init, command_init);
END_CTOR
main
int Command(void)
{rt_uint8_t count;rz_command_obj_init();rz_command_t * pobj = rz_command_obj_get();for(count = 0 ; count < 3 ;count++){ pobj->rz_command_parse(pobj,count);rt_thread_mdelay(100);}return 0;
}
MSH_CMD_EXPORT(Command, RT-Thread first Command sample);
总结
- 在命令模式中,将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作模式或事务模式。
- 命令模式的主要优点在于降低系统的耦合度,增加新的命令很方便,而且可以比较容易地设计一个命令队列和宏命令,并方便地实现对请求的撤销和恢复;其主要缺点在于可能会导致某些系统有过多的具体命令类。
- 命令模式适用情况包括:需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互;需要将一组操作组合在一起,即支持宏命令。
C语言实现设计模式—命令模式相关推荐
- C语言设计模式——命令模式
C语言设计模式--命令模式 好处:让代码清晰明了,容易添加和删除,易维护. 哪些地方会用到命令模式?(列出几个常见的例子) 1.按键处理,每个按键按下得到一个索引(指的就是命令),一个按键对应一个处理 ...
- Python设计模式-命令模式
Python设计模式-命令模式 代码基于3.5.2,代码如下; #coding:utf-8 #命令模式class barbecuer():def bakeButton(self):print(&quo ...
- 设计模式 命令模式 实例_根据您的命令-命令设计模式
设计模式 命令模式 实例 命令设计模式是一种广为人知的设计模式,属于行为设计模式("四人帮"的一部分). 顾名思义,它与应用程序中的动作和事件有关. 问题陈述: 假设有一个网页将在 ...
- 游戏设计模式 - 命令模式在Unity中的应用(C#)
游戏设计模式 - 命令模式在Unity中的应用(C#) 实测:这是一篇简单易懂的文章-> https://zhuanlan.zhihu.com/p/46937284
- C语言实现设计模式—模板模式
文章目录 C语言实现设计模式-模板模式 模板模式介绍 UML用例说明 实际场景使用 框架结构[共用框架]-通用的串口协议分析函数 不同实现-数据类型区别 C语言实现设计模式-模板模式 模板模式介绍 在 ...
- C++设计模式——命令模式(command pattern)
一.原理讲解 别名动作(action),事务(transaction). 1.1意图 将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作 ...
- 【知识分享】C语言中的设计模式——命令模式
背景 命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式.请求以命令的形式包裹在对象中,并传给调用对象.调用对象寻找可以处理该命令的合适的对象,并把该命令传给 ...
- C语言实现设计模式-策略模式+命令模式组合使用
文章目录 使用环境介绍 使用策略模式-区分使用哪种方法 使用命令模式-区分哪种命令动作 使用环境介绍 当主设备和从设备使用串口信息交互通讯,根据串口协议,实现对从设备的控制访问. 使用情况1:当主设备 ...
- 游戏设计模式---命令模式
命令模式 游戏设计模式Design Patterns Revisited 命令模式是我最喜欢的模式之一. 大多数我写的游戏或者别的什么之类的大型程序,都会在某处用到它. 当在正确的地方使用时,它可以将 ...
最新文章
- latex实现横竖均居中
- 向vSphere迁移虚拟机,Converter需要升级至4.0.1
- JS获取当前对象大小以及屏幕分辨率等...
- 百信银行基于 Apache Hudi 实时数据湖演进方案
- java转换工具类_Java数据转换工具类
- java资源分配算法,java - 资源分配与动态规划算法 - 堆栈内存溢出
- 学习笔记5-C语言-数组
- java获取cpu使用率_再一次生产 CPU 高负载排查实践
- 搜索引擎的强大意味着与之合作就会双赢?
- 计算机系统维护认识,计算机系统维护试验讲解
- 我的U盘,在某台机器上所有文件大小为0
- 读《About Face 4 交互设计精髓》7
- 如何解决“配置系统未能初始化“ 错误的解决方案?
- 《大数据之路-阿里巴巴大数据实践》第十六章 数据应用
- Heading/Pitch/Roll与Omega/Phi/Kappa简单介绍
- python搬家具_Python面向对象实现案例———摆放家具
- 实现在线预览 pdf 以及添加水印
- 一日一命令:find 命令详解
- Windows无法安装,选中的磁盘为GPT分区形式 --解决办法
- 四川大学计算机学院男女生比例,2019年四川各大高校男女比例排行,电子科技大学4比1...