欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

软件构造笔记(四):Spec、AF和RI

程序员文章站 2024-02-09 18:06:00
...

前言

        本文将介绍一些关于ADT设计中Spec、AF和RI的细节。由于内容较为细碎,为了加强理解,特将该部分知识点列出来,进行简单归纳总结。

一. Spec

        刚开始接触软件构造时,关于规约Spec的概念便已经有所接触,但真正开始逐步认识还是在实验中设计规约的时候。

(一)含义

        Spec是程序员在设计ADT时对自己所写方法的规约,它规定了方法应该做什么,不应该做什么。而在接下来的设计中,测试用例的编写就需要依靠Spec的描述,因为程序员所编写的代码必定是符合spec的,否则就是不合格的。同时,有了Spec的存在,客户端在使用代码时就会有所依据,好的Spec可以大大节省客户端使用自己的API时所需要的时间,并且大大降低了客户端对自己所编写的代码的误解。

(二)内容及评判标准

        Spec的主要内容分为以下三部分:

        1. 前置条件precondition:这是对客户端的约束,是用户在使用方法时必须满足的条件。在Java中一般使用声明@param说明每个参数的前置条件。

        2. 后置条件postcondition:这是对开发者的约束,也是方法结束时设计者必须满足的内容。在Java中一般使用如下两种声明,其内容及用途如下:

        @return:对后置条件的说明,一般为返回值;
        @throws:说明出现异常的时候会发生什么,一般为异常处理方式。

(三)Spec强弱

        若想要Spec变强,可以采用如下方式:

        1. 更宽松的前置条件

        2. 更严格的后置条件

        如果是用椭圆在图中对不同的Spec强弱进行表示,则越小(包含的结果的点越少)的椭圆,其Spec越强,此处我们可以理解为:椭圆的大小代表了开发者的*度。

(四)注意事项

        程序员应该通过Spec让客户端轻松地知道他需要为这个方法提供什么样的参数,以及会得到什么样的结果,但不应该让用户知道方法的内部逻辑是怎么样的,以避免恶意用户对代码结构的破坏。

二. AF和RI

        由于AF和RI之间存在映射关系,因此可以将两者放在一起进行讨论。

(一)含义

        RI:Rep Invariant。其中Invariant是不变量的意思,是ADT的功能中任何时候都应该满足的一些条件。

        AF:Abstraction Function。代表抽象函数。

(二)具体表示

        AF和RI中的A和R分别代表两个空间:R是内部表示的空间,是开发者关注的内容;而A是ADT能表示的存在于实际的对象,一般是由客户所关注的。

        而AF就是从R空间到A空间的一个映射,作为解释函数,对A空间的每一个对象,在R空间中都至少由一种属性或类型与之对应,因此该映射是一个满射

        而RI是一个集合,是R空间中所有值的子集,包含了所有合法的表示值。checkRep()方法就是用来随时检查RI是否被满足的。

        此处附上自己在lab2中写过的AF、RI,以及Safety from rep exposure的描述:

// Abstraction function:
    // AF(vertices) = 点集
    // Representation invariant:
    // 无重复点
    // Safety from rep exposure:
    // private final List<Vertex<L>> vertices

(三)注意事项

        RI、AF存在如下关系:

        相同的R可能存在不同的RI;

        即使是同样的R、 RI,也可以根据解释不同,而获得不同的AF;

        两个ADT有相同的rep和相同的AF,但其R也不—定相同。

        不应该给client看的内容有AF、RI、Rep exposure safety argument、testing strategy、Rep、Implementation和Test cases等等,留给client的只有Spec

总结

        本文主要解释了一些ADT设计中关于Spec、AF和RI的含义、内容、注意事项等内容。其细节部分相对琐碎,但是在实际应用中非常重要,因此应该牢记,并在日后有需求的时候活学活用。