目录链接
- Part I Functions & methods in programming languages
- Part II Specification: Programming for communication
-
- 2.1Documenting in programming
- 2.2Specification and Contract
- 2.3Behavioral equivalence
- 2.4Specification structure: pre-condition and post-condition
- Part III Designing specifications
-
- 3.1Classifying specifications
- 3.2Diagramming specifications
- 3.3Designing good specifications
文章的内容是我在复习这门课程时候看PPT时自己进行的翻译和一些总结,如果有错误或者出入希望大家能和我讨论!同时也希望给懒得翻译PPT而刷到这篇博客的你一些帮助!
Part I Functions & methods in programming languages
在这里我们先来了解一些基础概念以及他们通俗易懂的解释,为之后的规约书写打下基础。
-
Method:
Method意思是方法。在一个类中可以定义很多个方法,它就像是这个类的一部分,在创建一个这个类的实例化的时候,可以通过调用类中的方法来实现一些功能。有的类中可能会包含一个主方法,可以通过运行这个主方法来实现一个类似客户端的界面。
-
Parameters:
Parameters意思是参数。这就不用多说了吧,在定义一个方法或者函数的时候进行传递的就是参数咯。值得提醒的是,参数类型是否匹配在静态类型检查阶段完成。
-
Return Values:
Return values意思是返回值。在定义方法的时候需要规定该方法的返回值,如果方法无返回值则使用修饰符。同样的,返回值类型是否匹配也发生在静态类型检查阶段。
做一个形象的比喻吧,方法可以想象成程序的积木,可以被独立开发、测试、复用。使用方法的客户端,无需了解方法内部具体如何工作,这也就是抽象的含义。下面放一个完整的规约。
Part II Specification: Programming for communication
标题译为规约——通信编程。
2.1Documenting in programming
拿Java的API接口描述作为一个例子如下图。可以看到它写下了有关变量类型的记录,并假设你使用某一种数据类型。实际上,Java会在编译的时候检查你所做的假设,并且保证你的假设程序得其他地方不会被违反。同样的final关键字决定了你的设计决策,就是不可改变,也会在编译的时候进行静态检查。(注:这里的假设的意思我的理解是:假设所描述的内容就是方法的功能和参数,假设方法使用什么样的数据类型的参数以及返回值来达到某种功能。个人认为其实可以理解为规约。)
2.3Behavioral equivalence
这一部分讲述行为等价性。去判断行为等价性,问题的关键就在于两种实现方法能否相互替代。我们看一下下面两段代码:
这两个方法的目标分析起来是一样的,都是采用遍历的方法查询指定元素并返回元素下标,只是在细枝末节的地方有细微的差异。当指定元素的值没有找到的时候会返回数组长度而会返回-1;再有多个元素与目标值相同的时候,会返回第一个遇见的元素而会返回最后一个。
但是,当每一种值在这个数组中只出现一次的时候两个方法的行为就是等价的,所以对于这样的客户来说,两种方法具有行为等价性。总结的来说,行为等价性是站在客户端的角度来讲的。
简短的总结一下:单纯地看代码实现是不足以判定Implmentation是否是行为等价的,需要结合开发者和客户端之间的Spec进行判断。因此,在编写代码之前,需要弄清楚Spec如何协商形成、如何撰写。
2.4Specification structure: pre-condition and post-condition
规范的规约是有规范的结构的,有前置条件和后置条件。
-
前置条件Precondition:
requires。规约的前置条件是对客户端的约束,即客户端在使用这个方法的时候必须要满足的要求。 -
后置条件Postcondition:
effects。规约的后置条件是对开发者的约束,即开发人员在完成方法后需要满足的条件。 -
异常行为Exceptional behavior:
规约中做的规定,如果违反前置条件那么方法会怎么做,返回什么值。
规约还定了这样一个契约:如果前置条件满足了,那么后置条件也一定要被满足,即返回合适的值、抛出指定的异常或是修改或者不修改对象等等。那么同样的,如果前置条件没有被满足,那么方法可以做任何事情,客户端违约在先,实现着自然不需要遵守承诺。
在一个规约中,它可以描述方法的输入参数和返回值,但是他一定不可以涉及到实现着在实现过程中使用的到的本地变量或者方法内部的区域。
3.3Designing good specifications
是什么让你的方法变得更好strong>写一个很棒的方法首先要写一个很好的规约。一个好的方法设计并不是在于代码写得多么好,而是对方法的Spec有一个好的设计。好的规约应该是简洁清晰,有良好结构并且容易读懂的。有这样的规约一方面客户端用着舒服,另一方面开发者编程也更加清晰。
-
内聚的:
Spec描述的功能应该单一、简单、易于理解。他不应该有很多种情况的分述,比如`if-statements“等等。让我们看看下面这个例子:
–足够强壮的:
对于一些太弱的规约,客户端在使用的时候也不能放心,因为它给出的承诺太少了,因此,开发者应该尽可能考虑到所有的特殊情况,给出处理措施。下图中的例子就没有阐明如果遇到了null之后参数怎么变化,以及已经改变了的参数是否要保留。
客户端不喜欢太强的Precondition,不满足Precondition的输入会导致失败。惯用做法是:不限定太强的Precondition,而是在Postcondition中抛出异常:输入不合法。是否使用前置条件取决于:
- 检查的代价
- 方法的使用范围
如果只在类的内部使用该方法(private),那么可以使用前置条件(方法内部不需要判断输入是否满足,认为client会保证前置条件),在使用该方法的各个位置进行检查,并将责任交给内部客户端;
如果在其他地方使用该方法(public),那么可以不使用/放松前置条件(在方法内部检查输入是否满足),若客户端不满足则方法抛出异常。
这一部分的知识到此就结束了,感谢你能看到这里,说明你真的有好好学习。如果你觉得我写的还行,还请一键三连!

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91528 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!