【发布时间】:2010-10-26 19:54:41
【问题描述】:
背景:
我们正在为新的嵌入式系统建模固件。目前固件正在UML中建模,但不会使用UML建模工具的代码生成功能。
目标语言将是 C(具体来说是 C99)。
低功耗(即性能、快速执行)和正确性很重要,但正确性是重中之重,高于一切,包括代码大小和执行速度。
在对系统进行建模时,我们已经确定了一组定义明确的组件。每个组件都有自己的接口,并且许多组件与许多组件交互。
模型中的大多数组件将是实时操作系统 (RTOS) 下的单个任务(线程),尽管有些组件只不过是库。任务完全通过消息传递/队列发布相互通信。与库的交互将以同步函数调用的形式进行。
由于建议/建议可能取决于规模,我将提供一些信息。现在可能有大约 12-15 个组件,可能会增长到大约 20 个?不是 100 多个组件。假设平均而言,每个组件与 25% 的其他组件交互。
在component diagram 中,有端口/连接器用于表示组件之间的接口,即一个组件提供另一个组件所需的东西。到目前为止一切顺利。
问题来了:在很多情况下,我们不希望“组件 A”能够访问“组件 B”接口的所有,即我们希望将组件 A 限制为组件 B 提供的接口的子集。
问题/问题:
是否有一种系统的、相当直接的方法来强制执行(最好是在编译时)组件图上定义的接口契约?
显然,编译时解决方案优于运行时解决方案(更早的检测、更好的性能、可能更小的代码)。
例如,假设库组件“B”提供函数 X()、Y() 和 Z(),但我只希望组件“A”能够调用函数 Z(),而不是 X() 和Y()。同样,即使组件“A”可能能够通过其消息队列接收和处理大量不同的消息,但我们没有任何组件能够向任何组件发送任何消息。
我能想到的最好办法是为每个组件-组件接口设置不同的头文件,并且只公开(通过头文件)组件允许使用的接口部分。显然这可能会导致大量的头文件。这也意味着组件之间的消息传递不会直接使用 OS API 完成,而是通过函数调用完成,每个函数调用都会构建并发送特定的(允许的)消息。对于同步调用/库,只会公开允许的 API 子集。
在这个练习中,你可以假设人们会表现得很好。换句话说,不用担心人们会直接欺骗和剪切和粘贴函数原型,或者包含他们的头文件。再不允许。如果不允许,他们不会直接从“A”向“B”发布消息,依此类推……
也许有一种方法可以通过编译时断言来强制执行合同。也许有一种更优雅的方法可以在运行时检查/执行它,即使它会产生一些开销。
代码必须干净地编译和 lint,所以“函数原型防火墙”方法是可以的,但似乎有一种更惯用的方法来做到这一点。
【问题讨论】:
标签: c interface uml design-by-contract contract