Ahm*_*med 5 c c++ architecture software-design clean-architecture
我正在从 Robert C. Martin 的《Clean Architecture》一书中学习建筑。本书强调的主要规则之一是 DIP 规则,该规则规定源代码依赖项必须仅指向内部,指向更高级别的策略。尝试将其翻译到嵌入式领域假设 2 个组件scheduler和timer. 调度程序是高级策略,它依赖于低级计时器驱动程序,需要调用 API get_current_time(),set_timeout()我只需将模块拆分为一个实现文件timer.c和一个标头(一个接口?)timer.h,并且scheduler.c可以简单地包含timer.h使用这些 API 。读这本书将前面的场景描述为违反了依赖关系规则,并暗示应该实现两个组件之间的接口来打破依赖关系。
例如,要模仿 c 中的情况,timer_abstract可以包含带有函数指针的通用结构
struct timer_drv {
uint32 (*get_current_time)(void);
void (*set_timeout)(uint32 t);
}
对我来说,这看起来像是过度设计。一个简单的头文件还不够吗?C 头文件可以被视为接口吗?
在计算中,“接口”是两个或多个组件或子系统交换信息的公共边界。
C 或 C++ 中的头文件是一个文本文件,其中包含一组声明和(可能)宏,可以将其插入到编译单元(源代码的单独单元,例如源文件)中,并允许该编译单元使用这些声明和宏。换句话说,在后续编译之前,源文件中的内容会被 C 或 C++ 预处理器#include "headerfile"的内容替换。headerfile
基于这些定义,我不会将头文件描述为接口。
头文件可以定义数据类型、声明变量和声明函数。多个源文件可能包含该标头,并且每个源文件都能够使用该标头中声明的数据类型、变量和函数。一个编译单元可以包含该标头,然后定义标头中声明的一些(或全部)函数。
然而,类型、变量和函数不需要放置在头文件中。有足够决心的程序员可以手动将声明和宏复制到使用它们的每个源文件中,并且从不使用头文件。AC 或 C++ 编译器无法区分 - 因为预处理器所做的只是文本替换。
声明和宏的逻辑分组实际上代表了一个接口,而不是向编译单元提供有关接口的信息的方式。头文件只是一种(可选)方式,通过它可以将一组声明和宏提供给编译单元。
当然,头文件在实际中通常用于避免使用一组声明和宏时出现错误 - 因此可以帮助更轻松地管理由这些声明和宏表示的接口。头文件的每个编译单元#include接收相同的内容(除非受到其他预处理器宏的影响)。这比程序员手动将声明复制到每个需要它们的源文件中更不容易出错。它也更容易维护 - 编辑头文件意味着所有编译单元都可以重建并且可以看到更改。然而,手动将声明和宏更新到每个源文件中可能会引入错误,因为程序员很容易出错 - 例如,通过在源文件之间不一致地编辑声明。
| 归档时间: |
|
| 查看次数: |
3234 次 |
| 最近记录: |