0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

真刀真枪模块化(2)—图解Service模型

电子设计 作者:电子设计 2020-12-14 22:38 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

作者: GorgonMeducer 傻孩子
首发:裸机思维

【说在前面的话】

在前面一篇文章《真刀真枪模块化(1)——一本糊涂账》中,我们讨论了:

在工程开发中进行模块化的本来目的——为了复用已有的代码,节省当前项目的开发时间;

实际操作过程中遇到的尴尬问题——模块的具体实现原本应该被视作黑盒子,程序员因为各种心理上的原因要阅读代码;

以及

“原则上”的解决方案——严禁程序员在项目开发过程中阅读模块的具体实现代码。

道理说起来简单,真要实际操作起来,一线开发人员往往会直摇头:手中已有的所谓“模块”质量参差不齐、模块的开发者鱼龙混杂、很多模块别说出了问题要找开发方负责维护了,就是原作者是谁恐怕都找不到了——在这种情况下,大谈“禁止开发人员阅读模块的实现代码”,简直就是天方夜谭,颇有几分“何不食肉糜”的傲慢。
——难道模块化本身错了么?实际情况并非如此,这里傻孩子忍不住想“感慨”两句:在追求和实践新的方法(论)的时候,总难免会遇到这样那样的困难,有的困难甚至让整个方案看起来“完全行不通”——在这种时候,如果立即退出来将整个方法全盘否定,就会失去宝贵的前进机会。
在模块化的过程中,要想发挥模块化“复用已有代码”、“降低开发时间”的作用,就必须将模块视作黑盒子;一旦模块被视作黑盒子,实现的质量和后续的可靠维护就成为当前模块是否可用的基石——进一步来说,不靠谱的代码实现和差强人意的接口设计与封装是导致模块化失败的根本原因。
本文将为您介绍一种模块化封装的简单操作方式——由傻孩子根据十多年工程实践经验总结、历经无数商业项目的千锤百炼。通过这一方式构建的模块,我称之为服务(Service),因此,这里所要介绍的模型又被称之为“Service模型”。

【正文】

从具体操作层面来说,所谓Service模型并不复杂。
首先,每一个模块都有一个属于自己的专门的文件夹,文件夹的名称与模块名相同:

其次,每一个模块中都有一个专门的头文件,用于提供给模块的使用者来包含(#include);该头文件的名称必须与模块的名称相同。

需要特别强调和说明的是:

该头文件用于“从模块内部向模块外部”提供使用模块所必须的“最小信息”;

任何人要使用模块,必须且只能包含该头文件;

我们把这类向模块的使用者提供必要信息的头文件称之为接口头文件;

接口头文件遵循“最小信息公开原则”,即,该头文件中只存放用户使用模块最少最少所必须知道的信息。实际操作中,类型定义、宏定义、函数和全局变量声明都应该首先放置在对应的源代码中(或是后面会提到的模块内私有的接口头文件中);当且仅当我们发现用户要使用模块的某一功能必须要用到某一信息时,才“极不情愿”地、“抠门”的、且尽可能将其它能剥离和隐藏的信息剥离开后,放置到接口头文件中。

与接口头文件相对,每一个模块内部都会有一个专门的头文件用于实现对模块的配置:

该头文件用于“从模块外部向模块内部”输入配置信息;

如无特殊说明或安排,该头文件应该固定命名为 app/_cfg.h(没有额外的前缀和后缀);

如无特殊说明或安排,该头文件应该仅包含配置信息,例如:宏定义、类型定义(在极其特殊的情况下,偶尔出现的全局变量或者函数声明);

我们把这类头文件称之为“配置头文件”;

在构建和使用模块的时候,无论是模块的设计者还是模块的使用者,都应该遵循黑盒子原则,在操作上表现为——模块的使用者不应该修改任何位于模块文件夹内部的内容——模块文件夹既是黑盒子的容器,也是黑盒子的边界。
为了遵守这一原则,模块内部的配置头文件实际上是不允许用户去修改的——那么这又如何让用户更改对模块的各个配置选项呢?答案很简单,如下图所示:模块内部的app/_cfg.h 在文件的一开始会首先包含上一级目录的app/_cfg.h。

为了实现这一点,一个模块内部 app/_cfg.h 的固定内容格式为:

//!作为模块的用户,不要修改这里的任何内容

一个模块的接口头文件,其内部格式可能为:

//!作为模块的用户,不要修改这里的任何内容

可以很容易注意到,当使用某一模块时,用户可以很方便的在模块外部定义一个属于自己的 app/_cfg.h 来向模块提供配置信息——而无论如何修改这一文件,都不会破坏黑盒子本身的内容。
再次,一个模块往往拥有一个或多个C源文件,它只需要包含模块的接口头文件,就可以共享一些“对外公开的信息”。

这里有个朋友会问了:根据最小信息公开原则,接口头文件中只包含了一些最小信息,如果模块内的多个C源文件之间需要共享一些非公开的私有信息,该怎么处理呢?
为了解决这一问题,我们一般会引入一个以双下划线为前缀的接口头文件(比如,叫做/_/_common.h),并视其为模块的私有财产。如下图所示,这一头文件是仅供模块内的源代码包含的——无论是模块的接口头文件还是模块的配置头文件都不应该对其进行包含——以防信息泄露:

一个典型的 /_/_common.h 内容如下:

/*!作为模块的用户,不要修改这里的任何内容,理论上也不应该关心这

基于这一规则,模块内一个可能的C源文件内容如下:

//! 作为模块的用户,不要修改这里的任何内容

最后,一个模块内是允许包含其它子模块的,对于这种嵌套情况,仅需要两步骤就可以完成部署:

将子模块拷贝到父模块中,或者按照前述的模块构建规则,在父模块中建立一个子模块;

父模块的接口头文件包含子模块的接口头文件

少数情况下,如果子模块与父模块高度耦合(一般来说就是在父模块中从头开始建立一个新的子模块时会发生这种情况)——比如子模块依赖父模块的 /_/_common.h 中提供的信息,则应该在子模块中也建立一个 /_/_common.h,并仿照 app/_cfg.h 的做法,在头文件的一开始首先向上包含父模块的 /_/_common.h;

如果父模块包含/_/_common.h,而子模块并不需要这一信息,则子模块无需在做任何特殊修改。

对app/_cfg.h来说,由于子模块原本就会自动包含上一级的app/_cfg.h,因此,我们无须做任何特殊操作,子模块就可以透过父模块的app/_cfg.h自动从外界获取配置信息——这就像是一种标准化的水管安装。

以上就是使用Service模型进行模块化的基本规则。是不是很简单?

【后记】

Service模型本身是完全本着简化用户操作的宗旨,以实用性为重中之重,同时也避免一切“反直觉”的设定。
对用户来说,这一模型是非常友好的:

只需要拷贝模块目录就可以完成部署;

只需要在模块的外部额外添加一个app/_cfg.h就可以实现对模块的配置;

所有关于模块的使用信息(使用说明书)都放置在一个唯一的、与模块同名的接口头文件中;且这里包含的信息对用户来说都是可用的(没有无用信息,也没有多余信息);

对模块的开发者来说:

这一模型是高度遵守黑盒子原则的;

用户使用模块,是不需要“用脏手染指”自己宝贵的代码的(无需修改);

对制作 Library 非常友好,只需要保留接口头文件,而将其它所有文件(包括源代码和私有接口头文件)删除并保留一个固化好的app/_cfg.h即可。

模块是非常容易迁移和嵌套的。

当然,这一Service模型也有一个小缺点(可能有些人也对此无法容忍),即,用某些工程管理工具将头文件的包含关系展开时,通常会看到海量的app/_cfg.h(尽管他们内部都使用了模块特有的保护宏进行区别)——对于这一问题,在真刀真枪模块化的后续内容中,将提供一个较为完美的解决方案,这里就先卖个关子——对普通用户来说,现有的Service模型足够了。

审核编辑 黄昊宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模型
    +关注

    关注

    1

    文章

    3876

    浏览量

    52343
  • Service
    +关注

    关注

    0

    文章

    33

    浏览量

    14391
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    英飞凌低压驱动可扩展功率演示板:模块化设计与应用指南

    英飞凌低压驱动可扩展功率演示板:模块化设计与应用指南 在电力电子设计领域,评估新型功率MOSFET解决方案并比较其性能,需要一个具备功能完备且布局特性可比的硬件平台。英飞凌的低压驱动可扩展功率演示板
    的头像 发表于 05-19 10:15 212次阅读

    探索SOLAHD SHP系列重型模块化电源:高功率与灵活性的完美结合

    哪些独特的特性和优势。 文件下载: SH304LS0Z.pdf 产品概述 SOLAHD SHP系列是一系列高功率、智能模块化电源,功率范围从1500瓦到4920瓦。其模块化设计为工程师们提供了极大的灵活性,能够轻松定制出不寻常的电压和功率组合。同时,智能
    的头像 发表于 05-09 14:15 102次阅读

    美的与吉宝携手推出AI智能模块化制冷解决方案,覆盖亚洲市场

    。   Signing Ceremony 本次合作为非排他性合作。美的楼宇科技在暖通空调制造及智能楼宇系统领域的技术能力,将与吉宝在"制冷即服务"(Cooling-as-a-Service, CaaS)及数字优化方面的优势深度融合,共同推动标准
    的头像 发表于 04-15 16:39 243次阅读
    美的与吉宝携手推出AI智能<b class='flag-5'>模块化</b>制冷解决方案,覆盖亚洲市场

    LuatOS 系统框架的模块化设计原理

     LuatOS 的设计核心在于高度模块化与松耦合架构。系统将硬件驱动、通信协议、定时任务等封装为独立模块,通过统一的注册与回调机制接入主事件循环。这种设计不仅提升了代码复用率,也使得开发者可以按需
    的头像 发表于 02-03 15:56 381次阅读
    LuatOS 系统框架的<b class='flag-5'>模块化</b>设计原理

    模块化高精度铷原子钟存在的意义

    在时频计量领域,铷原子钟以其稳定性和可靠性成为通信、导航、科研等领域的核心设备。西安同步电子科技有限公司的SYN3306型高性能铷原子钟,通过将10MHz输出设计为模块化结构,实现了从“单一功能设备
    的头像 发表于 01-21 19:09 319次阅读

    鼎阳科技推PXIe模块化示波器、PXIe模块化矢量网络分析仪产品组合,构建新一代模块化、软件定义的测试平台

    新品发布 2026年1月12日,鼎阳科技全新推出PXIe模块化示波器、PXIe模块化矢量网络分析仪和USB矢量网络分析仪三款新品,并同步推出三款PXIe嵌入式控制器与PXIe混合机箱。基于模块化架构
    的头像 发表于 01-14 10:35 6.6w次阅读
    鼎阳科技推PXIe<b class='flag-5'>模块化</b>示波器、PXIe<b class='flag-5'>模块化</b>矢量网络分析仪产品组合,构建新一代<b class='flag-5'>模块化</b>、软件定义的测试平台

    避繁就简!商汤日日新大模型灵性巧解数学难题,获赞“机器的审美”

    、字节跳动,让数学与AI同台碰撞,开展了一场真刀真枪的“图灵测试”。 现场,面对数学家抛出的难题,商汤科技“日日新”大模型在解答复分析计算积分、微分几何证明等问题中,展示了惊人的进化力。 在计算一个复杂的广义积分
    的头像 发表于 01-12 11:41 478次阅读
    避繁就简!商汤日日新大<b class='flag-5'>模型</b>灵性巧解数学难题,获赞“机器的审美”

    探索Amphenol RJE1Y系列模块化电缆组件的卓越性能

    探索Amphenol RJE1Y系列模块化电缆组件的卓越性能 作为电子工程师,在设计项目中,选择合适的电缆组件至关重要。今天,我们来深入了解Amphenol的RJE1Y系列模块化电缆组件,看看它能
    的头像 发表于 12-11 14:25 589次阅读

    Amphenol RJE88系列模块化插孔:LAN应用的理想之选

    Amphenol RJE88系列模块化插孔:LAN应用的理想之选 在电子产品设计中,选择合适的连接器对于设备的性能和稳定性至关重要。今天我要给大家介绍的是Amphenol的RJE88系列模块化插孔
    的头像 发表于 12-11 14:05 590次阅读

    Amphenol RJE1D系列模块化插孔:高性能网络连接的理想选择

    Amphenol RJE1D系列模块化插孔:高性能网络连接的理想选择 在当今高速发展的网络通信领域,可靠且高性能的连接器对于确保数据的稳定传输至关重要。Amphenol的RJE1D系列模块化插孔
    的头像 发表于 12-10 09:35 585次阅读

    新品发布|LRM模块化高速连接器

    认证发明专利。该款连接器是一种模块化、高性能高速率的系统连接器产品,多腔体模块化设计可以支持多种信号类型,射频、高频高速、光信号及电源的混合传输,不同的腔体可以灵
    的头像 发表于 10-20 17:02 2490次阅读
    新品发布|LRM<b class='flag-5'>模块化</b>高速连接器

    新品推荐|模块化集成式高速连接器

    LRM连接器随着电子技术的快速发展,在电力传输、工业自动、航空航天等领域,对高效、稳定、可靠的电气连接解决方案的需求日益增长。因此日晟万晟开发了新一代模块化集成式高速连接器-LRM系列,该款连接器
    的头像 发表于 07-07 18:15 1850次阅读
    新品推荐|<b class='flag-5'>模块化</b>集成式高速连接器

    鸿蒙5开发宝藏案例分享---模块化设计案例分享

    鸿蒙模块化开发大揭秘!官方隐藏案例实战指南 大家好呀! 最近在HarmonyOS文档里挖到一个宝藏——官方其实藏了大量模块化设计案例!很多小伙伴可能没注意到,今天我就带大家手把手拆解这些黄金实践,附
    发表于 06-12 16:17

    原理图模块化,BOM 物料位号处理

    原理图模块化,把常用的模块保存成一个PART(在TOOL 菜单下 选择 Generate Part)。保存成OLB格式。使用的时候,就像使用元器件一样,从库里面拖出来直接放到原理图上即可。 问题是
    发表于 06-09 19:27

    什么是模块化计算机?搞清楚用途和应用场景,别再瞎选了!

    如果你是搞工业自动、医疗设备、交通控制,甚至是军事装备的,那你大概率已经听过“模块化计算机”这个词。要是你还没了解,那这篇文章就是为你写的。作为一个在工业计算领域摸爬滚打十多年的从业者,我可以很负责任地说:模块化计算机不是未来
    的头像 发表于 06-04 11:00 1288次阅读
    什么是<b class='flag-5'>模块化</b>计算机?搞清楚用途和应用场景,别再瞎选了!