在进行实验二的过程中经常需要为ADT添加以上描述,在此进行一下总结和整理,从而进一步加深印象和理解。
1.RI(Representation invariant):表示不变量。
RI即ADT中的属性必须满足的条件,其目的是确定取值是否合法,以预先防止程序运行时可能出现的部分错误。
比如在实验二中,我们构建有向图时需要输入边的权值,而权值不可为负,否则为不合法的边。所以我们在编写Edge类的RI时,需要限定weight > 0。随后我们可以在Edge类中根据RI编写checkRep函数来检查这些不变量。
·checkRep()函数
该函数根据RI的内容进行编写,用于检查表示不变量。一般使用断言(assert)进行检查,如果没有通过,则取值发生错误,需要对其进行检查与修改。
2.AF(Abstraction function):抽象函数。
AF类似一个映射,由表示空间(Rep)向抽象空间(Abstract)进行映射。
·关于表示空间与抽象空间:
抽象空间即抽象值构成的空间。用户(client)只关注抽象空间A,因为用户只需要知道如何使用即可,无需关心内部实现的方法,故抽象空间内的抽象值是client看到和使用的值。
表示空间啥由表示值构成的空间。ADT实现者(server)关注表示空间,但同样需要对抽象空间和表示空间都有清晰的把握,从而把握ADT的构造,避免发生exposure。
·AF一定是满射,但不一定是单射,所以也不一定是双射。即,表示空间中的对象不一定在抽象空间中有对应值,但抽象空间中的对象在表示空间中一定有对应值。以一个通俗的例子来讲,如果将表示空间内的对象比作萝卜,抽象空间内的对象比作萝卜坑,则AF可以描述为:萝卜不一定都栽在坑里,但每个坑里一定会有萝卜。
关于RI和AF的一些总结
·对于同一个ADT可以有多种表示,而不同的内部表示则需要设计不同的RI和AF。
·即便是同样的表示空间,也可以有不同的RI。
·即便是同样的表示空间与RI,其AF也可能不相同,即"解释不同"。
3.Rep Exposure:表示泄露。
Java中的数据类型可分为mutable(可变)和immutable(不可变)两种。其中,mutable类数据上进行的操作会改变内部数据,immutable类则会构造新的对象,不会改变原本对象的内部值。所以在使用mutable类数据时,会容易产生表示泄露,从而对程序的安全性造成威胁。
防止表示泄露的方法主要有以下几种:
·使用防御式拷贝。
·使用private和final关键字进行修饰,使内部属性不被用户得到,也不能被修改与继承。
·尽可能使用immutable数据类型。