第五章 设计规约

参数类型,返回值类型是否匹配,都在静态检查阶段完成
签名以及签名上面的都是规约,规定参数、返回值类型
一.规约:程序员和用户之间的一种约定
1.代码中蕴含的“设计决策”:给编译器读
2. 注释形式的“设计决策”:给自己和别人读
3.规约优点:
(1)隔离“变化”,无需通知客户端
(2)提高代码效率,不必对非法输入进行处理
(3)扮演“防火墙”,调用端不需要知道实现,实现者不需要知道客户怎么使用
(4)不需要了解具体实现
4.规约明确规定:
(1)输入输出数据类型
(2)功能和正确性
(3)性能
5.行为等价性
(1)同一个方法可以写不同规约,通过规约判断方法本身等价性
(2)站在客户端看行为等价性(结合规约,不单单看程序端 P27)
6.前置条件和后置条件
(1)前置条件(requires),输入,对客户端的约束,在使用方法时必须满足的条件
(2)后置条件(effects),输出–有时将异常也放入输出里面,只不过不是正常输出,对开发者的约束,方法结束时必须满足的条件
契约:如果前置条件满足了,后置条件必须满足
前置条件不满足,则方法可做任何事情(后置条件可以是任意)P34
前置条件若违反,没有义务提醒,但是可以通过快速找bug来进行修复
静态类型声明是一种规约,可据此进行静态类型检查static checking
编程语言:前置@param,后置@return/@throws
规约的注释必须是开头两个星,结尾一个星;参数值和返回值类型不写
在这里插入图片描述
7.局部变量和私有域不要写
(1)表示泄露,知道内部怎样实现,用户依赖局部变量和私有域写程序,自己的就不能改了
8.一些原则
(1) 除非在后置条件里声明过,否则方法内部不应该改变输入参数
(2)尽量不设计mutating的spec
(3)除非spec必须如此,否则不应修改输入参数
(4)尽量避免使用mutable的对象
记录每个参数、返回值、每个异常(已检查和未检查)、方法的功能,包括目的、副作用、任何线程安全问题、任何性能问题
黑盒测试就是根据规约设计测试用例,不考虑实现,和其他客户一样
二.设计规约
1.对规约分类
spec变强:更放松的前置条件+更严格的后置条件
确定的规约:给定一个满足precondition的输入,其输出是唯一的、明确的
欠定的规约:同一个输入可以有多个输出
非确定的规约:同一个输入,多次执行时得到的输出可能不同
操作式规约:操作规范给出了该方法执行的一系列步骤,例如伪代码
声明式规约:没有内部实现的描述,只有“初-终”状态
2.更强的规约:放松对客户端的要求,对开发者要求更严格
3.Diagramming specifications
在这里插入图片描述
矩形代表一个规约所有实现,点代表具体实现,椭圆代表这些具体实现到底有多少种
某个具体实现,若满足规约,则落在椭圆范围内;否则,在其之外
程序员可以在规约的范围内自由选择实现方式
客户端无需了解具体使用了哪个实现,只需要根据规约进行合理调用即可
更强的规约,表达为更小的区域
(1)更强的后置条件意味着实现的自由度更低了➔在图中的面积更小
(2)更弱的前置条件意味着实现时要处理更多的可能输入,实现的自由度低了➔面积更小
(3)规约更强的方法可以替换规约更弱的方法
4.设计好的规约
(1)Spec描述的功能应单一、简单、易理解
(2)调用的结果应该提供信息,不能让客户端产生理解的歧义
(3)规约应该足够强,开发者应尽可能考虑各种特殊情况,在post-condition给出处理措施
(4)规约尽量用抽象类型,给开发者和客户端更大的自由度,例如用List替代ArrayList
5.前置条件和后置条件
不限定太强的precondition,而是在postcondition中抛出异常:输入不合法
尽可能在错误的根源处fail,避免其大规模扩散
如果只在类的内部使用该方法,则可以使用前置条件(方法内部不需要判断输入是否满足,认为client会满足前置条件),在使用该方法的各个位置进行检查–责任交给内部client
如果在其他地方使用该方法,则可以不设置/放松前置条件(方法内部检查),若不满足则抛出异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值