版权声明:本文为博主原创文章,遵循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(); }
}

  

在其外部文件中,调用相对应的初始化函数以及逻辑函数,但是当我们项目很复杂的时候,逻辑关系也层层覆盖、交替的时候,这样的写法就有些不是很好看了。

接口适配器

首先我们还是要来定义数据结构,一般这样的项目分为这样几个步骤:

  1. 初始化
  2. 输入
  3. 处理
  4. 输出

我们把这四个步骤封装起来,再定义数据结构如下:

 
// 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语言实现状态机(实用)

【编程之美】超时重传,滑动窗口,可靠性传输原理C语言实现

【编程之美】论嵌入式架构的重要性

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

  1. 【Android 应用开发】Android 网络编程 API笔记 - java.net 包相关 接口 api

    Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...

  2. Android 网络编程 API笔记 - java.net 包相关 接口 api

    Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...

  3. java并发编程之美-阅读记录1

    1.1什么是线程? 在理解线程之前先要明白什么是进程,因为线程是进程中的一个实体.(线程是不会独立存在的) 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程中的 ...

  4. 【编程之美】2.5 寻找最大的k个数

    有若干个互不相等的无序的数,怎么选出其中最大的k个数. 我自己的方案:因为学过找第k大数的O(N)算法,所以第一反应就是找第K大的数.然后把所有大于等于第k大的数取出来. 写这个知道算法的代码都花了2 ...

  5. 【编程之美】CPU

    今天开始看编程之美 .第一个问题是CPU的使用率控制,微软的问题果然高大上,我一看就傻了,啥也不知道.没追求直接看答案试了一下.发现自己电脑太好了,4核8线程,程序乱飘.加了一个进程绑定,可以控制一个 ...

  6. 编程之美_1.1 让CPU占用率曲线听你指挥

    听到有人说让要写一个程序,让用户来决定Windows任务管理器的CPU占用率. 觉得很好奇.但第一个想法就是写个死循环.哈哈.不知道具体的占用率是多少,但至少能保证在程序运行时,CPU的占用率终会稳定 ...

  7. 编程之美的2.17,数组循环移位 & 字符串逆转(反转) Hello world Welcome => Welcome world Hello

    代码如下:(类似于编程之美的2.17,数组循环移位) static void Main(string[] args) { string input = "Hello World Welcom ...

  8. [质疑]编程之美求N!的二进制最低位1的位置的问题

    引子:编程之美给出了求N!的二进制最低位1的位置的二种思路,但是呢?但是呢?不信你仔细听我道来. 1.编程之美一书给出的解决思路 问题的目标是N!的二进制表示中最低位1的位置.给定一个整数N,求N!二 ...

  9. 编程之美 两个叶子的节点之间 最大距离 变种 leecode

    提交地址: https://oj.leetcode.com/problems/binary-tree-maximum-path-sum/ 说一下思路http://www.cnblogs.com/mil ...

随机推荐

  1. eclipse添加方法注释

    打开注释模板编辑窗口:Window ->Preferences->java -> Code Style -> Code Template->Comments type 设 ...

  2. django-admin和manage.py用法

    官网文档地址:django-admin和manage.py 金句: 所有的天赋,都来自于你对你喜欢的某种事物的模仿与学习,否则你就不会有这种天赋. 开篇话: 我们在Django开发过程中,命令行执行最 ...

  3. ntp和chrony

    目录 chrony 简介 ntp pool ntp 配置文件 chrony 配置文件 chronyc 命令行工具 修改时区 chrony 简介 chrony 是 RedHat 开发的,它是网络时间协议 ...

  4. python 基础篇 模块化

    在做项目的时候,虽然你不可能把全世界的代码都放到一个文件夹下,但是类似模块化的思想还是要有的--那就是以项目的根目录作为最基本的目录,所有的模块调用,都要通过根目录一层层向下索引的方式来 import ...

  5. 如何用TensorFlow实现线性回归

    环境Anaconda 废话不多说,关键看代码 import tensorflow as tf import os os.environ['TF_CPP_MIN_LOG_LEVEL']='2' tf.a ...

  6. php的echo 和 return的区别

    来源:https://blog.csdn.net/ljfphp/article/details/76718635 项目中碰到的问题,本来是想在控制器直接return $xml的($xml是一段xml格 ...

  7. linux 批量删除文件

    来源;https://www.cnblogs.com/sinpo/p/7106998.html linux下批量删除文件   1. 在linux批量删除多级目录下同一格式的文件,可采用find + e ...

  8. 2019-2020-1 20199310《Linux内核原理与分析》第四周作业

    1.问题描述 在前面的文章中,已经接触过一些Linux内核的知识,本文将进一步从Linux内核源代码的目录结构入手,在Oracle VM VirtualBox的Linux环境中构造一个简单的操作系统M ...

  9. 2019-2020-1 20199328《Linux内核原理与分析》第六周作业

    使用gdb跟踪分析一个系统调用内核函数 首先我们删除本身的menu目录,并从github上克隆一个menu,并进行编译 编译过程 现在找到test.c文件,加入上个实验中做的getPid()方法 利用 ...

  10. Java程序员必备基础结构图

    前言 最近看了深入理解Java虚拟机第三版,整理了一些基础结构图,算是比较全的了,做一下笔记,大家一起学习. 1.Java虚拟机运行时数据区图 JVM内存结构是Java程序员必须掌握的基础. 程序计数 ...