HIT软件构造复习:chapter5

第五章讲了规约设计的规范和重要性

首先要先搞清楚一些东西,方法就是类中一些功能函数,它的签名就是一些基本属性,包括方法的名字、可见性、返回值、引用参数,而我们的规约就跟这些属性有关。

这些属性的检查都发生在编译阶段。

客户端只需要知道方法的这些签名,无需知道具体实现,例如排序方法不需要知道具体使用了什么排序算法等等。这样做的目的不仅是避免信息泄露,也放宽设计的细节要求,只要达到目的即可,不在乎实现方法。

通常来说,方法的结构如下:先是规约,再是实现体。

规约的格式如上,与注释不同,开头需要/**引起,@param来引出对参数的规约,@return引出对返回值的规约,其他部分是对这个方法的功能的简述,注意一定不能将具体实现的细节暴露给客户端。代码本身就代表程序员的设计思想,但是阅读起来麻烦,尤其是内容比较复杂,客户又没有编程基础时,因此用这种“简述”的形式来描述对程序的大致要求是比较合适的。代码更偏向程序员与机器的交互,而规约就是程序员和客户的交互。

规约更像是一种契约关系,将客户端与程序员联系起来,为程序员指派任务,为客户说明用途和使用规范。这种契约的责任关系双方都需要遵守,程序员方不必多谈,自然要按规定完成任务;与之前理解比较不同的是,当客户违反了规约要求的使用规范时,我们无需按照原有的规约为其返回适当的值,简单来说这个时候我们进行任何处理都是合理的,即便是对异常输入不做任何处理,因为客户违约在先。

除此之外,由于有规约的存在,程序员对具体实现做出改变时无需对客户端通知。

还有一点,当我们的部分设计直接实现比较困难时,或是为了设计更加简便,可以把输入责任通过规约交给客户端。

行为等价性:用户在客户端视角判断某两个方法是否等价时,由于上述的约定,客户端不知道实现的细节,因此只要在前置条件(一般即传入的参数)满足的情况下,后置条件(一般即返回值或是抛出的异常)也一致,就可以认为这两个方法等价。

许多详细的规约实现可以参考Java许多类/接口的方法的API文档,例如大数类的加法:

 除非规约中有强调,否则尽量避免在方法实现中修改输入的参数;同时我们没办法完全强迫方法的实现体和客户端不保存可变变量的别名,为解决此现象带来的困扰,在规约中限定这些数据不可变。遵循不可变性,可以减少bug。

规约对于测试也是很有帮助的,尤其是黑盒测试。我们可以直接根据规约内容写测试,因为黑盒测试同样不关心内部实现细节,因此在未实现方法之前就可以写测试,这也是测试优先编程理念的正确性的验证。需要注意的是,在根据规约写测试时,一定不要强迫具体实现细节:例如规约只提到搜寻某个元素,但并没有说明是找到第几个,所以我们测试时,应该只测试找到的是不是与该元素相等,而不能测试其具体序号。

规约的规范要求

1.对前置、后置条件的描述一定不能有歧义,必须是陈述

2.陈述内容一定不能涉及实现细节

规约的强弱:对于两个规约s1、s2,如果s1的前置条件不强于s2,但是s1的后置条件不弱于s2的后置条件,那么就认为s1不弱于s2,通俗来说就是要求更少但承诺更多,这个时候就可以用s1替换s2。

规约的强度越高,程序员的责任越重,客户端的责任越轻。

我们可以用范围图描述规约:

矩形框表示值域,椭圆区域表示符合规约的所有情况,每个点都表示一个对应前置条件、后置条件组成的情况,点落在椭圆内表示符合规约。

 

之前提到规约的强弱,在图示中,椭圆包含于另一椭圆内时,表示规约较强。根据判断规约强弱的规则不难知道,很多规约没法比较强弱,这种表现为两个椭圆没有包含关系(可能相交,可能独立)。另外,当椭圆更小时,只能说明符合这个规约的情况数较少,不一定能说明强弱。

课中提到一个让我豁然开朗的理念:好的方法设计往往指的是好的规约设计而非代码实现

好的规约应该有如下几个特点:

1.信息足够丰富:用尽量简明的描述把所有可能的情况和对应的返回说清楚,不让用户阅读时有歧义

2.内聚的:描述的功能应该单一、易懂,如果有不相关操作合并在一起,应该将之分离成多个方法

3.强弱应该适中:太强的规约会对我们的代码设计产生困扰,太弱的设计会让客户对此方法不够放心

4.自由:在规约中,尽可能使用抽象数据类型而不指出具体的数据类型,否则会对实现产生限制,而且会把信息暴露给客户端

5.根据检查输入参数的合理性的难易程度和方法的使用范围决定是否进行检测

如果只在类的内部使用该方法(private),那么可以使用前置条件(方法内部
不需要判断输入是否满足,认为client会保证前置条件),在使用该方法的各
个位置进行check——责任交给内部client;
如果在其他地方使用该方法(public),那么可以不使用/放松前置条件(在方
法内部检查输入是否满足),若client端不满足则方法抛出异常。
需要程序员进行权衡

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值