Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
ISO/IEC 25436定义了用于软件分析与设计的Eiffel方法——一种基于契约驱动的、严谨的面向对象系统构建方法。该方法由Bertrand Meyer创立并通过数十年的工业应用而逐步形式化。Eiffel方法将契约式设计(Design by Contract, DbC)置于核心位置:每个软件元素都通过前置条件、后置条件和类不变量明确指定其义务和收益。
契约式设计借鉴了商业合同的类比:例程(供应方)保证一个结果,前提是调用者(客户方)满足某些条件。该框架通过三种机制编码实现:
| 契约元素 | 角色 | 示例 | 违反后果 |
|---|---|---|---|
| 前置条件(require) | 调用者的义务 | pop操作前 “stack.count > 0” | 调用方过错——在调用方引发异常 |
| 后置条件(ensure) | 例程的义务 | pop操作后 “Result = old stack.top” | 例程过错——在例程中引发异常 |
| 类不变量 | 所有实例的恒真条件 | 所有STACK对象的 “stack.count >= 0” | 类实现不一致 |
ISO/IEC 25436将DbC从实现阶段扩展到分析和设计阶段。在分析阶段,契约捕获领域规则而不承诺实现细节:”取款交易不得超过当前账户余额。”在设计阶段,契约细化为软件组件接口:”withdraw(amount)例程要求balance >= amount,并确保balance = 旧balance – amount。”
Eiffel方法引入了业务对象表示法(Business Object Notation, BON),用于直观地表示类聚类——即协同完成系统职责的类组。与UML相对扁平的类图不同,BON强调聚类级别的关系:被复用的聚类、客户-供应依赖关系和继承层次结构都作为一等可视化元素呈现。
BON聚类图将类组织成圆角矩形(聚类),通过标记了客户-供应或继承关系的带标签边连接。每个聚类都带有一个显式的契约摘要,显示其公共例程的组合前置条件和后置条件。这使得架构师能够在聚类级别推理系统属性,而无需深入单个类的细节。
标准建议聚类大小不超过7-12个类,遵循米勒定律关于人类信息处理能力的限制。超过此大小的聚类应分解为子聚类,每个子聚类带有自己的契约摘要。这种层次化分解与ISO/IEC 25435中原始控制操作的组合规则相呼应,在分析、设计和实现之间创建了一致的知识框架。
在开发组织中采纳ISO/IEC 25436需要在三个维度上进行变革:工具、流程和文化。
工具:Eiffel方法由EiffelStudio支持,提供集成的契约编译、运行时断言监控和自动文档生成。对于使用其他语言的团队,DbC可以通过库实现(Java的Contracts、Python的PyContracts、.NET的Code Contracts),但缺乏同等水平的语言集成度。
流程:契约编写应集成到每个用户故事的完成定义中。一个故事在所有受影响例程的前置条件、后置条件和不变量被指定之前不算完成。这条规则防止了在进度压力下无限期推迟契约编写的常见模式。
文化:Eiffel方法需要从防御式编程向基于契约的编程转变。在防御式编程中,每个例程检查所有内容;在DbC中,各方只检查自己的义务。这通过消除冗余检查减少了代码膨胀,并明确了责任边界,但它要求组织信任供应方会履行其契约。