5 Designing Specification

笔者之前并无意识到规约的重要性,甚至认为那些不过是废话。但经过徐汉川老师的精心讲解下,才清楚规约的作用如此之大,规约如此的强大。

本文参考软件构造课来概述规约。(方法的规约 前置/后置条件 欠定规约、非确定规约 陈述式规约、操作式规约 规约的强度及其比较 如何写出好的规约)

首先 参数类型是否匹配,在静态类型检查阶段就完成了。

“方法”是程序的“积木”,可以被独立开发、测试、复用 使用“方法”的客户端,无需了解方法内部具体如何工作—“抽象”

上边是方法的规约 下边是方法的实现体。

为什么要写出“假设”?第一:自己记不住;第二:别人不懂。

代码中蕴 含的“设计决策”:给编译器读

注释形式的“设计决策”:给自己和别人读

没规约,没法分派任务,无法写程序;即使写出来,也不知道对错

程序与客户端之间达成的一致

Spec给“供需双 方”都确定了责任,在调用的时候双方都要遵守

很多bug来自于 双方之间的误解

不写下来,那么不同开发者的理解 就可能不同

没有规约 ,难以定位错误 精确的规约,有助于区分责任 客户端无需阅读被调用函数的代码,只需理解规约即可。规约可以隔离“变化”,无需通知客户端。规约也可以提高编码效率 (E.g., 实现者不需要写代码确保输入的正确性,调用者的责任。规约:扮演“防火墙”角色。客户端不需要知道实现。实现者不需要知道如何被使用。

 然后,我们谈谈前置条件与后置条件。

前置条件:对客户端的约束,在使用方法时必须满足的条件。后置条件:对开发者的约束,方法结束时必须满足的条件。契约:如果前置条件满足了,后置条件必须满足。

前置条件与后置条件的关系:

 前置条件满足,则后置条件必须满足。前置条件不满足,则方法可做任何事情。但是作为负责任的程序员:当前置条件被违反时,说明客户端有bug, 尽管实现者没有义务提醒,但可通过快速失败使bug更容易被找到和修复。

静态类型声明是一种规约,可据此进行 静态类型检查static checking。方法前的注释也是一种规约,但需人工判定其是否满足。

除 非在后置条件里声明过,否则方法内部不应该改变输入参数。应尽量遵循此规则,尽量不设计 mutating的spec,否则就容易引发bugs。程序员之间应达成的默契:除非spec必须如此,否则不 应修改输入参数。mutable对象会使规约复杂化。

Designing specifications

规约具有确定性 陈述性

规约的确定性(描述的输出是否确定)规约 的陈述性(只是描述了输出,还是描述了如何计算输出)

规约强度用来判断“哪个规约更好”

如何比较 两个规约,以判断是否可以用一个规约替换另一个?

规约的强度S2>=S1 前置条件更弱或相等(不强于) 后置条件更强或相等(不弱于) 就可以用S2替代S1

比如 如下的三个例子

对于这两个 前置条件更弱了 在满足条件下,后置条件无变化 故规约更强

 S1和S3并不可以比较

 规约的范围:

 程序员可以在 规约的范围内自由选择实现方式。

客户端无需 了解具体使用了哪个实现。更强的规约,表达为更小的区域。

更强的后置 条件意味着实现的自由度更低了 ➔在图中的面积更小

更弱的前置条件意味着 实现时要处理更多的可能输入, 实现的自由度低了➔面积更小

一个好的“方法”设计,并不是你的代码写的多么好,而是你对该方 法的spec设计的如何。

一方面:client用着舒服 

另一方面:开发者编着舒服

太强太弱的规约都有不合适的地方

太弱的spec,client不放心、不敢用 (因为没有给出足够的承诺)。 开发者应尽可能考虑各种特殊情况,在post-condition给出处理措施。

太强的spec,在很多特殊情况下难以达到,给开发者增加了实现的难 度(client当然非常高兴)。

归纳:是否使用前置条件取决于(1) check的代价;(2) 方法的使用范围 – 如果只在类的内部使用该方法(private),那么可以使用前置条件(方法内部 不需要判断输入是否满足,认为client会保证前置条件),在使用该方法的各 个位置进行check——责任交给内部client; – 如果在其他地方使用该方法(public),那么可以不使用/放松前置条件(在方 法内部检查输入是否满足),若client端不满足则方法抛出异常。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值