目录
一、函数和方法
参数类型和返回值类型是否匹配在静态类型检查阶段完成
方法可以被独立开发、测试、复用
使用方法的客户端,无需了解方法内部具体如何工作
二、规约
1.编程时记录
Java API Document:
类层次结构和实现的接口;
直接子类,接口的实现类;
类的描述;
构造方法的详细描述;
调用的方法的描述;
变量的数据类型定义;
返回值的含义等
代码中的设计决策:给编译器读;
注释形式的设计决策:给自己和别人读
2.规约(契约)
没规约不知道自己写出来程序的对错,同样契约也是程序和客户端之间达成的一致
spec给供需双方都确定了责任,在调用的时候双方都要遵守
规约可以隔离变化,无需通知客户端;
规约能提高代码效率;
规约扮演防火墙角色
规约包括:输入/输出的数据类型,功能和正确性,性能(只讲能做什么,不讲怎么实现的)
3. 行为等价性
根据规约判断两个函数是否等价(站在客户端视角看行为等价性)
4.规约结构
前置条件precondition:requires——对客户端约束,在使用方法时必须满足的条件(@param)
后置条件postcondition:effects——对开发者的约束,方法结束时必须满足的条件(@return、@throws)
契约:如果前置条件满足了,后置条件必须满足
spec只讨论方法的参数和返回值,不讨论方法的局部变量或私有域
除非在后置条件里声明过,否则方法内部不应该改变输入参数
尽量不涉及可变量的spec,否则容易引发bug
避免使用可变的全局变量(对程序安全性造成巨大破坏)
5.测试和验证规约
三、设计规约
1.分类的规约
规约具有正确性、陈述性、强度
前置条件更弱、后置条件更强,规约更强,可以取代更弱的规约
确定的规约:给定一个满足前置条件的输入,其输出是唯一的、明确的
欠定的规约:同一个输入可以有多个输出
非确定的规约:同一个输入,多次执行时得到的输出可能不同
操作式规约(例:伪代码)
声明式规约(更有价值):没有内部实现的描述,只有“初-终”状态
2.图形式规约
某个具体实现,若满足规约,则落在其范围内;否则,在其之外
程序员可以在规约的范围内自由选择实现方式
客户端无需了解具体使用了哪个实现
更强的规约表达为更小的区域
3.设计一个好的规约
言简意赅、客户端用着舒服、开发者编着舒服
1.spec应是内聚的:描述的功能单一、简单、易理解
2.信息丰富(不能让客户端产生理解的歧义)
3.规格应该足够强
4.太强的spec在很多特殊情况下难以达到,给开发者增加了实现的难度
5.在规约里使用抽象数据类型,可以给方法的实现体与客户端更大的自由度
6.在方法正式执行之前,要检查前置条件是否已满足(不满足就抛出异常)