一个合格的平台化组件应该是什么样的(linux C语言)

2024-03-11 23:48

本文主要是介绍一个合格的平台化组件应该是什么样的(linux C语言),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1. 为什么要开发平台化组件
    • 2. 平台化组件是什么
        • 2.1 平台化组件的定义
        • 2.2 定义说明
    • 3. 如何做好平台化
        • 3.1 合理的开发目录
        • 3.2 框架必要结构
        • 3.3 开发&维护流程
        • 3.4 组件更新日志类型
        • 3.5 平台化组件代码基本规则
        • 3.6 平台化组件代码必要注释信息
        • 3.7 平台化组件版本说明
        • 4.8 自动化处理脚本工具
    • 4. 几个思考
    • 5. 结尾

1. 为什么要开发平台化组件

  • 项目或者业务越来越复杂的情况下,组件化开发更适合快速迭代,在添加修改组件时候不需担心影响其他组件
  • 解决业务模块划分不清晰,耦合度大,较难维护
  • 可单独开发,测试,发布一个组件,不需要像以前一样开发完某个功能,就需要编译、运行、打包整个项目
  • 某个组件出现问题,可直接对组件进行处理,不必担心会因为修改而影响到整个工程
  • 组件划分后,组件的开发不受其他业务影响,可以多个组件并行开发,加快开发进度
  • 组件可以很好的提升代码的可重用性(而非可复制性),如果有其他项目需要该组件可以直接引入使用,而不是拷贝代码,拷贝资源等
  • 组件单独测试方便,测试完成后进行集中测试,如果后期有修改组件,只要组件提供的能力或者接口不发生改变,就不需要再次进行集中测试,减少测试工作量
  • 如果有新人的加入,可以直接分配组件进行开发,而非需要熟悉整个项目,可以从一个组件的开发使新进人员比较快速熟悉项目、了解到开发规范
  • 组件中包含有基础组件,这些组件也算是技术的一种积累,为未来开发新项目提供更快速的响应
  • 可以更早下班

组件化就是将一个产品拆分成一个个小的功能模块,每个功能模块完成属于自己这部分独立的功能,使得整个项目的管理和维护变得非常容易。
保证代码在高质量完成需求的同时具备良好的可读性、可维护性。

2. 平台化组件是什么

2.1 平台化组件的定义
  • 一个包含源代码、说明文档、demo、成果物自动输出脚本的代码目录
  • 一个源代码为高内聚低耦合的代码集合
  • 一个源代码至少包含组件初始化组件销毁组件运行组件回调函数注册四大接口的框架
  • 一个可适用于多个嵌入式平台的组件
2.2 定义说明
  • 高内聚低耦合:demo可单独运行在嵌入式平台
  • 上述四大接口需要在对外提供的头文件中体现
  • 组件初始化:分配组件运行需要的空间与资源,如存放回调函数结构体的内存,初始化锁、信号量等
  • 注册回调函数:组件与外部调用者之间的协议数据交互、日志回调函数注册
  • 组件运行:数据收发、流程处理
  • 销毁组件:释放组件相关资源

3. 如何做好平台化

3.1 合理的开发目录
Component_name          //平台化组件名称
├── Makefile            //打包生成库
├── README.md           //简要说明组件用途
├── demo                //演示组件库接口使用
│   ├── Makefile
│   └── src
├── docs                //存放组件相关文档
│   ├── 使用说明.html
│   ├── 使用说明.md
│   ├── 概要设计.doc
│   └── 详细设计.doc
├── include             //组件需要依赖的头文件
├── lib                 //组件需要依赖的库
├── src                 //组件源代码
├── test                //单元测试代码
├── third_party         //组件需要依赖的第三方源码
├── tools               //组件相关的工具,如脚本
└── output              //组件输出成果物└── gcc-arm-none-xxx                //交叉编译链└── Component_name              //组件名称├── include                 //对外提供头文件│   └── Component_name│       └── Component_name.h└── lib                     //对外提供封装库└── libComponent_name.a
  • makefile的编写方法参考我这篇文章
3.2 框架必要结构
  • 大多数情况下,至少包含组件初始化组件销毁组件运行组件回调函数注册四大接口的框架
  • 开源框架参考:https://github.com/jobbole/awesome-c-cn#frameworks
3.3 开发&维护流程
  • 开发流程
确认需求
编写原理文档
建立平台化组件开发目录
确定代码主要框架
编写确定对外提供头文件
编写单元测试代码
编写demo代码
开发组件代码
单元测试和demo验证
  • 维护流程
邮件发布组件
源码or库+头文件
使用文档
协助第一次集成,接收各产品线反馈
调整组件,更新文档
单元测试和demo验证
3.4 组件更新日志类型
  • [ADD]新增
  • [OPT]优化
  • [CHG]修复
  • [DEL]移除
3.5 平台化组件代码基本规则

代码中,如果不符合以下原则,必须特别说明。
以下规则的目的是为了降低开发中犯错的概率,仅供参考

  • 变量定义时必须赋初值
  • 较大的内存要从堆上分配,不能从栈上分配
  • switch语句必须有default选项
  • switch语句中,每个case必须加break(多个case有相同处理流程除外)
  • if语句必须有else项,如果if语句内含有不会依次向下执行的语句除外(return,break,continue)
  • if语句中,变量与0做比较
    • 布尔:if(flag), if(!flag)
    • 整型:if(0 == value), if(0 != value)
    • 指针:if(NULL == ptr), if(NULL != ptr)
    • 浮点:const float EPSINON = 0.00001; if ((x >= - EPSINON) && (x <= EPSINON)
  • 遇到if/else/return的组合,应该写为 return (condition? x:y);
  • 不要用return语句返回指向“栈内存”的指针
  • 定义一个结构体必须要对齐(提高内存空间利用率,在内存共享的情况下防止数据错位)
    https://blog.csdn.net/TAlice/article/details/82016508?spm=1001.2014.3001.5501
  • 不允许使用全局变量,但可以使用静态全局变量(防止增大代码耦合度)
  • 只在当前C文件内调用的函数,定义时必须加上static关键字
  • 循环操作里要有超时机制
  • 禁止对指针求sizeof,这样做有可能会将指针的长度视为指针所指向地址的长度,导致犯错
  • 函数入参必须检查其合法性
  • 添加必要的注释,但没有注释比错误的注释好(保证必要的注释的正确性)
  • 代码的编写要简单易懂,同时要考虑到后期的低成本维护
  • C语言写的代码,声明时需加宏限制
    #ifdef __cplusplus
    extern "C" {
    #endif#ifdef __cplusplus
    }
    #endif
    
3.6 平台化组件代码必要注释信息
  • 文件头版权信息

/**********************************************************************************      Copyright:  (C) 2018 Wang Tao*                  All rights reserved.**       Filename:  thread.c*    Description:  This file *                 *        Version:  1.0.0(2018年05月15日)*         Author:  wang tao <TAlicer@163.com>*      ChangeLog:  1, Release initial version on "2018年05月15日 00时34分04秒"*                 ********************************************************************************/
  • 函数说明信息
/** @brief Example function for orange project *  * Example text * * @param[in] param1    description for param1* @param[out] param2    description for param2* @return none*/
3.7 平台化组件版本说明

软件和说明文档版本A.B.C这些数字分别代表什么意思
以Spark1.6.0为例子来说明。

- 第一个数字:1
major version : 代表大版本更新,一般都会有一些 api 的变化,以及大的优化或是一些结构的改变;
- 第二个数字:6
minor version : 代表小版本更新,一般会新加 api,或者是对当前的 api 就行优化,或者是其他内容的更新,比如说 WEB UI 的更新等等;
- 第三个数字:0
Patch version,代表修复当前小版本存在的一些 bug,基本不会有任何 api 的改变和功能更新;
4.8 自动化处理脚本工具
  • 当前工具能自动生成平台化组件目录、必要基础文档框架、基础Makefile框架,链接
  • 使用方法:
wangtao@DESKTOP-1D526UH:~/Demo$ ./cmptTool.sh
Please input Component_name:test_component
Please input Author_name:wangtao
Successfully generated test_component

4. 几个思考

  • 需求与代码哪个重要?

    • 并不是所有的产品都能提出合理的需求,当你面对一个提出不合理需求的产品的时候,你需要坚持自己的原则,不能妥协。
  • 什么是测试驱动代码?

    • 测试驱动代码,你写的代码要可以执行单元测试。如果你发现你的代码很难写单元测试,那么你就要思考你的代码是不是已经不整洁了,或者说已经乱成一团了。
  • 什么是简单的代码?

    • 能通过所有测试
    • 如果某段代码在程序设计中反复出现,就证明想法在代码中没有很好的体现出来。总之,不要重复代码,只做一件事,小规模抽象。
  • 平台化组件向外(各产品线)提供成果物的形式(库or源码)

    • 不做平台化:前期快、中期慢、后期更慢
    • 提供成果物的形式-源码:前期慢、中期快、后期慢
    • 提供成果物的形式-库:前期慢、中期快、后期更快

    那我们到底要如何抉择:

    • 无论哪一种,都应该以开发一个库的标准去要求自己,这样才能保证代码的高内聚与高度模块化
    • 建议先以源码的形式提供平台化组件,等功能稳定、对外接口固定后再以库+头文件的形式提供平台化组件
  • 单元测试在实际过程中存在的问题(以下观点来自某大佬)
    作为C程序员,为什么我们在工作过程中很少被要求做单元测试,以至于工作一两年之后甚至都没听说过单元测试,但是大多数开源项目都是有做单元测试的?我认为有以下几点原因:

    • C程序员大部分都是做嵌入式工程师,偏底层,多多少少都和硬件沾边,以至于弱化了软件设计;
    • 嵌入式岗位的产品大多数做是靠实体产品挣钱,不是靠软件服务,普遍不注重软件维护;
    • 单元测试也是写代码,也会占用工作时间,上班的都知道,工作是做不完的,所以不愿意去写单元测试;
    • 公司决策,公司、部门专注于产品快速迭代,以完成软件功能为首要,反正有专门的测试团队,要求程序员快速完成功能,却不对代码质量做把控;
    • 开源项目不一样,开源项目可能会被每个程序员查看,代码写得太差,可没关注量,个人、团体、公司的形象就上不去;
    • 开源项目一般都会持续迭代,使用单元测试优势特别明显,能快速迭代,快速测试;而且开源项目由于其特性,以至于每个人都可以使用简单的环境进行测试,如果使用人工测试的方法就很难满足;
    • 开源项目使用的技术理念相对比公司内更激进,接纳意愿更高,大环境也更容易满足。

    那我们到底要如何抉择:

    • 写良好的软件,我认为应该是每个程序员的基本专业、职业素养,要有这样的心态去写代码;
    • 如果你的公司、部门要求做单元测试,我觉得这是幸运的;
    • 如果公司没要求,你可以提建议,谈谈单元测试的优势,要是有不可逆因素拒绝了你的提议,那你可以在开发之余为你的代码编写单元测试;
    • 如果你是在做开源项目,应该没有太多说的,懂的都懂。
      从cmockery入门C语言单元测试

5. 结尾

不知不觉,毕业已经快三年了,见过很多很好的代码,也见过不少的烂代码。最后我几乎绝望的发现,无论是谁写的代码,只要经过时间的洗礼,都会变成一堆屎山。我们就像不断重复把一块巨石推上山顶的西西弗斯,而我们唯一能做的,就是向好代码学习,向烂代码反省。正如团长说的那样,“一尘不染的事情是没有的,我们每天都在吸进灰尘,但不妨碍把事情做得好一点啊。”

这篇关于一个合格的平台化组件应该是什么样的(linux C语言)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/799475

相关文章

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Linux samba共享慢的原因及解决方案

《Linuxsamba共享慢的原因及解决方案》:本文主要介绍Linuxsamba共享慢的原因及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux samba共享慢原因及解决问题表现原因解决办法总结Linandroidux samba共享慢原因及解决

新特性抢先看! Ubuntu 25.04 Beta 发布:Linux 6.14 内核

《新特性抢先看!Ubuntu25.04Beta发布:Linux6.14内核》Canonical公司近日发布了Ubuntu25.04Beta版,这一版本被赋予了一个活泼的代号——“Plu... Canonical 昨日(3 月 27 日)放出了 Beta 版 Ubuntu 25.04 系统镜像,代号“Pluc

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

Linux安装MySQL的教程

《Linux安装MySQL的教程》:本文主要介绍Linux安装MySQL的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux安装mysql1.Mysql官网2.我的存放路径3.解压mysql文件到当前目录4.重命名一下5.创建mysql用户组和用户并修

Linux上设置Ollama服务配置(常用环境变量)

《Linux上设置Ollama服务配置(常用环境变量)》本文主要介绍了Linux上设置Ollama服务配置(常用环境变量),Ollama提供了多种环境变量供配置,如调试模式、模型目录等,下面就来介绍一... 目录在 linux 上设置环境变量配置 OllamPOgxSRJfa手动安装安装特定版本查看日志在

C语言中的数据类型强制转换

《C语言中的数据类型强制转换》:本文主要介绍C语言中的数据类型强制转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C语言数据类型强制转换自动转换强制转换类型总结C语言数据类型强制转换强制类型转换:是通过类型转换运算来实现的,主要的数据类型转换分为自动转换