长话短说:我越来越意识到,C接口和低级别的东西会导致在设计代码时遵循良好的C++思想时出现困难。
那么,我现在想要什么?我正在寻找一些文献,类似于“Effective C ++”,但专门针对那些必须处理低级别方面的人。
常见的架构是使用金字塔布局进行抽象化。最底层知道硬件的具体情况。每向上一层,则越来越远离硬件,逐渐接近应用程序。
这里的想法是,与单个硬件项相关的所有内容都应在其封装中。共享相同功能但位于不同地址的常见设备应从单个接口继承。例如,假设有三个位于地址0x1000、0x2000和0x3000处的USB端口,它们的使用方式相同,唯一的区别是它们的硬件寄存器位于不同的地址。因此,应该有一个USB_Interface_Base_Class,以及3个实例或3个子类。
USB类别应该只暴露基本功能。类别的使用者不关心硬件寄存器,只关心进行I/O操作。因此,详细信息对于类别的外部用户是隐藏的。
在研究和开发过程中,硬件是易变的,可能在生产过程中发生改变。目标是减少变更的传播。例如,如果将USB接口更改为无线电接口,则硬件访问层应更改,但更改不应深入应用程序。需要更改的模块越少,就越好。
每个远离硬件的层次应比前一个较低的层次具有更高级别的抽象。
例如,最高级别的执行操作为:`cout << "Hello\n"`; 下一层可以缓冲数据并调用“驱动程序”。 驱动程序表示它想要与字符输出设备交互。默认字符设备连接到USB。 USB驱动程序与硬件接口通信以设置寄存器并传输数据。
在最高层次上,用户想要将文本输出到默认输出端口,这就是抽象。下面的层填充细节以完成工作。
两个或多个模块之间的依赖关系称为耦合。从紧密到松散有不同程度的耦合。当一个模块的内部更改需要对另一个模块进行更改时,两个模块被认为是紧密耦合的。当一个模块的内部更改不影响另一个模块时,两个模块被认为是松散耦合的。
松散耦合的目标是帮助减少整个系统中的变化传播。如果一个模块访问另一个模块的数据成员并且数据成员发生更改,则调用模块需要更改。如果调用模块使用接口,则提供程序可以更改其数据成员而不会影响调用模块。变化的传播已经停止。
访问硬件不仅仅是编码。首先应考虑封装、变化传播、抽象和耦合原则。访问硬件的代码应遵循这些原则。一个好的过程是在编码之前考虑这些原则进行架构和设计。