理解“形式化方法”是迈向高阶软件工程思维的关键一步。这不仅仅是学习一种技术,更是从“实现功能”向“保证正确性”的思维转变。
1. 什么是形式化方法?
简单来说,形式化方法是基于数学的软件开发技术。
在传统的面向对象编程中,我们通常用自然语言(中文或英文)写需求文档,用UML画图。但自然语言往往有歧义,UML图有时也不够精确。
形式化方法使用形式化规约语言(基于数学逻辑)来精确描述系统的行为。它主要包括两个核心部分:
- 形式规约:用数学公式定义系统“应该做什么”。
- 形式验证:用数学推导证明系统“做得对不对”。
2. 为什么要引入形式化方法?
在面向对象设计中引入形式化方法,主要为了解决以下问题:
- 消除二义性:数学语言是精确的。例如,规定
age >= 0,计算机就能严格判断,不会有“年龄应该是正数吧?”这种模糊理解。 - 早期发现错误:在写代码之前,通过检查规约就能发现逻辑漏洞(比如死锁、状态不可达)。
- 契约式设计:这是面向对象中最重要的应用。它强制要求代码实现必须满足预先定义的“契约”(前置条件、后置条件、不变式)。
3. 核心概念:契约式设计
它将程序看作一系列“契约”的集合。你需要掌握以下三个关键词:
表格
| 关键词 | 含义 | 作用 |
|---|---|---|
| 前置条件 | 方法执行前必须满足的条件 | 调用者的责任(例如:传入参数不能为null) |
| 后置条件 | 方法执行后必须保证的结果 | 被调用者的责任(例如:返回列表不为空,且包含新元素) |
| 类不变式 | 对象在其生命周期内始终保持为真的属性 | 保证对象状态的一致性(例如:人的年龄永远不能小于0) |
4. 常见的形式化工具与语言
通常会涉及以下两种具体的形式化描述方式:
A. JML
JML 是一种专门用于 Java 的规格语言,它以注释的形式写在代码中。
B. UML 与 OCL
虽然 UML 类图是图形化的,但为了使其精确,通常会配合OCL使用。OCL 是一种形式化语言,用于在 UML 模型上添加约束。
- 例子:在 UML 类图中,你可以用 OCL 表达“一个订单必须至少包含一个商品”这样的约束,这是单纯画图无法表达的。