【编程之美】常用于单片机的接口适配器模式C语言实现

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lihuidashen/p/12875018.html
微信链接:https://mp.weixin.qq.com/s/rXfKnFrBY-9OjnzCgBtQ6g
前言
通俗的讲,适配器模式是将一个类的接口转换成客户希望的另外一个接口,在我们编写程序的时候,尤其是在我们使用到单片机做项目的时候,经常会用到。

但是往往我们做项目写程序的时候,并没有想到那么多,如果在不带操作系统的情况下,想要整个框架易于移植,易于理解,那么我们真的需要好好想想这个设计模式怎么写了。
下面我根据自己的项目经验,来说说适用于单片机的接口适配器模式的实现。大佬勿扰,多多指教。
一般实现
在我们做项目的时候,一般的实现,可能我们会这样写代码
// FileName: test.c
// 来源:公众号【技术让梦想更伟大】
#include <stdio.h>
#include “ExternModule.h” int main(void)
{ /*初始化*/
vAllInit(); while(1)
{ /*项目逻辑*/
vLogicModule1(); vLogicModule2(); }
}
在其外部文件中,调用相对应的初始化函数以及逻辑函数,但是当我们项目很复杂的时候,逻辑关系也层层覆盖、交替的时候,这样的写法就有些不是很好看了。
接口适配器
首先我们还是要来定义数据结构,一般这样的项目分为这样几个步骤:
- 初始化
- 输入
- 处理
- 输出
我们把这四个步骤封装起来,再定义数据结构如下:
// FileName: test1.c
// 来源:公众号【技术让梦想更伟大】
/* 适配器类型定义 */
struct _ADAPTER
{
void (*Init )( void ); //初始化函数
void (*Input )( void ); //输入转换函数
void (*Process )( void ); //处理函数
void (*Output )( void ); //输出转换函数
};
typedef struct _ADAPTER ADAPTER ;
那么初始化函数,我们先来这样定义
// FileName: test1.c
// 来源:公众号【技术让梦想更伟大】
/* 模块初始化 */
void moduleInit( ADAPTER *module )
{
if( module->Init != NULL )
{
module->Init();
}
}
模块的逻辑运行,我们可以这样使用
// FileName: test1.c
// 来源:公众号【技术让梦想更伟大】
/* 模块逻辑运行 */
void moduleRun( ADAPTER *module )
{
// 模块输入适配接口不为空,则执行输入适配操作
if( module->Input != NULL )
{
module->Input();
} // 模块处理接口不为空,则执行处理操作 // 模块输出适配接口不为空,则执行输出适配操作
}
在定好了这些数据结构以及封装之后,我们在每个子模块中都只需要调用这个模式即可。例如有一个需求,需要点一个灯,我们建立独立文件,在文件中申明
// FileName: led.c
// 来源:公众号【技术让梦想更伟大】
/*led灯运行 */
ADAPTER LedModule = { vLedInit, NULL, vLedRunModule, NULL };
那么接下来只需要对初始化函数,逻辑运行函数进行描述就可以了。同理,我们需要一个按键的功能,在另一个独立文件申请
// FileName: key.c
// 来源:公众号【技术让梦想更伟大】
/*按键运行 */
ADAPTER KeyModule = { vKeyInit, NULL, vKeyRunModule, NULL };
这样的话就便于我们拆分需求,便于移植,同时程序也就模块化了,最后我们在main文件中做的就是调用这些函数就行。我们需要这样做。
// FileName: main.c
// 来源:公众号【技术让梦想更伟大】
/*主函数 */
void main( void )
{ moduleInit( &LedModule );
moduleInit( &keyModule ); while( 1 )
{
moduleRun( &LedModule );
moduleRun( &keyModule );
} }
最后
main函数就是这么简单了,整个架构也是很清晰,体现出编程之美
推荐阅读

【编程之美】常用于单片机的接口适配器模式C语言实现的更多相关文章
- 【Android 应用开发】Android 网络编程 API笔记 - java.net 包相关 接口 api
Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...
- Android 网络编程 API笔记 - java.net 包相关 接口 api
Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...
- java并发编程之美-阅读记录1
1.1什么是线程? 在理解线程之前先要明白什么是进程,因为线程是进程中的一个实体.(线程是不会独立存在的) 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程中的 ...
- 【编程之美】2.5 寻找最大的k个数
有若干个互不相等的无序的数,怎么选出其中最大的k个数. 我自己的方案:因为学过找第k大数的O(N)算法,所以第一反应就是找第K大的数.然后把所有大于等于第k大的数取出来. 写这个知道算法的代码都花了2 ...
- 【编程之美】CPU
今天开始看编程之美 .第一个问题是CPU的使用率控制,微软的问题果然高大上,我一看就傻了,啥也不知道.没追求直接看答案试了一下.发现自己电脑太好了,4核8线程,程序乱飘.加了一个进程绑定,可以控制一个 ...
- 编程之美_1.1 让CPU占用率曲线听你指挥
听到有人说让要写一个程序,让用户来决定Windows任务管理器的CPU占用率. 觉得很好奇.但第一个想法就是写个死循环.哈哈.不知道具体的占用率是多少,但至少能保证在程序运行时,CPU的占用率终会稳定 ...
- 编程之美的2.17,数组循环移位 & 字符串逆转(反转) Hello world Welcome => Welcome world Hello
代码如下:(类似于编程之美的2.17,数组循环移位) static void Main(string[] args) { string input = "Hello World Welcom ...
- [质疑]编程之美求N!的二进制最低位1的位置的问题
引子:编程之美给出了求N!的二进制最低位1的位置的二种思路,但是呢?但是呢?不信你仔细听我道来. 1.编程之美一书给出的解决思路 问题的目标是N!的二进制表示中最低位1的位置.给定一个整数N,求N!二 ...
- 编程之美 两个叶子的节点之间 最大距离 变种 leecode
提交地址: https://oj.leetcode.com/problems/binary-tree-maximum-path-sum/ 说一下思路http://www.cnblogs.com/mil ...
随机推荐
- 小说免费看!python爬虫框架scrapy 爬取纵横网
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 风,又奈何 PS:如有需要Python学习资料的小伙伴可以加点击下方 ...
- python之excel表操作
python对excel表操作主要用到三个库,xlrd,xlwt,xlutils,分别用于excel表读,写,修改操作,以下将一个简单介绍 一.生成excel表:xlwt类 新建excel表,并写入数 ...
- C# 基础知识系列- 14 IO篇之入门IO
0. 前言 在之前的章节中,大致介绍了C#中的一些基本概念.这篇我们将介绍一下C#的I/O操作,这将也是一个小连续剧.这是第一集,我们先来简单了解一下C#中的I/O框架. 1. 什么是I/O I/O ...
- php 关于 & 引用赋值
$a = ; $b = ; echo $a . echo $b . $a = $b; echo $a . echo $b . $a = &$b; echo $a . echo $b . $a ...
- Android xUtils3.0使用手册(二) - 数据库操作
步骤: (1). 创建数据表: (2). DaoConfig 获取数据库的配置信息: (3). 获取数据库实例: x.getDb(daoConfig); (4). 数据库的增删改查. 1. 创建 ...
- SpringCloud系列之集成Dubbo应用篇
目录 前言 项目版本 项目说明 集成Dubbo 2.6.x 新项目模块 老项目模块 集成Dubbo 2.7.x 新项目模块 老项目模块 参考资料 系列文章 前言 SpringCloud系列开篇文章就说 ...
- Redis数据迁移的三个方法
为什么80%的码农都做不了架构师?>>> 1. rdb数据备份恢复方法 redis 127.0.0.1:6379> SAVE OK 或者 redis-cli -h 127. ...
- Redis(一):数据结构与对象
前言 本书是Redis设计与实现的读书笔记,旨在对Redis底层的数据结构及实现有一定了解.本书所有的代码基于Redis 3.0. 简单动态字符串 SDS Redis没有直接使用C语言中的字符串,而是 ...
- BeanDefinition源码解析
我们知道BeanDefintion定义了Bean在IoC容器内的基本数据结构.在学习IoC之前先了解BeanDefition对我们理解IoC容器是有帮助的. 首先BeanDefinition是一个接口 ...
- MySQL使用ProxySQL实现读写分离
1 ProxySQL简介: ProxySQL是一个高性能的MySQL中间件,拥有强大的规则引擎.官方文档:https://github.com/sysown/proxysql/wiki/下载地址:ht ...