MIT6.031 软件构造 Reading7阅读笔记Designing Specifications(设计规范)

1、文章链接

Reading 7: Designing Specifications

2、文章内容

此篇文章研究类了似行为的不同规范,并讨论它们之间的权衡。将探索是什么使某些规范比其他规范更好。从以下三个方面来比较:

  • 是否具有确定性,即,给出的是确定的postcondition,还是众多可能性中的一种。
  • 描述性多强,是说明了所有的步骤,还是只给出结果和输出与输入的关系。
  • 强壮性多高,postcondition和precondition的强度。

(1)确定性vs不确定性

确定性:当呈现满足前提条件的状态时,结果完全确定。只有一个返回值和一个最终状态是可能的。没有多个有效输出的有效输入。 

确定性差不等于不确定性,不确定性必须引入随机化元素。

(2)声明性vs操作性

操作规范给出了该方法执行的一系列步骤;伪代码描述是可操作的。 

声明式规范没有给出中间步骤的细节。

相反,它们只是给出最终结果的属性,以及它与初始状态的关系。

(3)更强vs更弱

为了回答这个问题,我们从逻辑中汲取强弱的概念。谓词 P 是更强比谓词 Q (并且 Q 是较弱比 P)如果匹配 P 的状态集是匹配 Q 的状态的严格子集。将“更强”视为更受约束或更严格,而“更弱”则受更少约束、更松散可能会有所帮助。例如,前提条件是对输入状态的谓词,因此使前提条件更强意味着缩小合法输入的集合。后置条件是对输出状态的谓词,因此更强的后置条件会缩小允许的输出和效果集。规范是实现的谓词,因此更强大的规范会缩小合法实现的集合。请注意,如果 P 和 Q 都不是另一个的子集,那么 P 和 Q 也可能无法比较——既不强也不弱。
规范 S2 强于或等于规范 S1 当且仅当

  • S2 的前提条件弱于或等于 S1 的前提条件,
    并且
  • 对于满足 S1 前置条件的状态,S2 的后置条件强于或等于 S1 的后置条件。

如果是这种情况,那么满足 S2 的实现也可以用于满足 S1,并且在程序中用 S2 替换 S1 是安全的。

前提条件较弱,但对于满足的前提条件的输入,后置条件也较弱。

(4)绘图规范

规范定义了所有可能实现空间中的一个区域。给定的实现要么按照规范运行,满足前置条件-隐含-后置条件契约(它在区域内),要么不符合规范(在区域外)。

  • 实施者可以自由地在规范内移动,更改他们的代码,而不必担心惹恼客户。这对于实现者能够提高算法的性能、代码的清晰度或在发现错误时改变方法等至关重要。

  • 客户不知道他们将获得哪种实施方式。他们必须尊重规范,但也可以自由地改变他们使用实现的方式,而不必担心它会突然中断。

(5)设计好的规范

①规范应该是连贯的 

一个连贯的规范对于它的客户来说是一个单一的、完整的单元是有意义的。规范不应该有很多不同的情况。长参数列表、启用或禁用行为的布尔标志以及复杂的逻辑都是麻烦的迹象。

②返回结果应提供信息

③规范应该足够强大

规范应该在一般情况下给客户足够强的保证——它需要满足他们的基本要求。在指定特殊情况时,我们必须格外小心,以确保它们不会破坏原本有用的方法。
④规范也应该足够弱

规范太强有时会缺少重要的细节,如果出现问题将可能是许多地方出现错误。

⑤规范应尽可能使用抽象类型

用抽象类型编写我们的规范为客户和实现者提供了更多的自由。在 Java 中,这通常意味着使用接口类型,比如Mapor Reader,而不是特定的实现类型,比如HashMap or FileReader

(6)关于访问控制

将方法设为公共还是私有的决定实际上是关于类契约的决定。程序的其他部分可以自由访问公共方法。公开一个方法,将它宣传为您的班级愿意提供的服务。如果您将所有方法公开——包括真正仅用于类中本地使用的辅助方法——那么程序的其他部分可能会依赖它们,这将使您更难更改将来上课。您的代码不会为更改做好准备

公开内部辅助方法也会给你的类提供的可见界面添加混乱。保持内部事物的私有性使您的类的公共接口更小且更连贯(意味着它只做一件事并且做得很好)。你的代码会更容易理解

当我们开始编写具有持久内部状态的类时,我们将在接下来的几个类中看到使用私有的更有力的理由。保护这种状态将有助于保护程序免受错误的影响。

(7)关于静态方法和实例方法

静态方法不与类的任何特定实例相关联,而实例方法(不带static关键字声明)必须在特定对象上调用。

实例方法规范的编写方式与静态方法规范的编写方式相同,但它们通常会引用调用它们的实例的属性。

3、心得感悟

与往常一样,我们的目标是设计规范,使我们的软件:

  • 远离错误。如果没有规范,即使对我们程序的任何部分进行最微小的更改,也可能是翻倒整个事情的多米诺骨牌。结构良好、连贯的规范可以最大限度地减少误解,并最大限度地提高我们在静态检查、仔细推理、测试和代码审查的帮助下编写正确代码的能力。

  • 容易理解。编写良好的声明性规范意味着客户不必阅读或理解代码。你可能从来没有读过的代码,这样做对 Python 程序员来说并不像阅读声明规范那样有用。

  • 准备好改变。适当弱的规范为实现者提供了自由,而适当强的规范则为客户提供了自由。我们甚至可以自己更改规范,而不必重新访问它们使用的每个地方,只要我们只是加强它们:削弱前置条件和加强后置条件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值