RI:R→boolean
For a rep value r, RI(r) is true if and only if r is mapped(映射) by AF.换句话说,RI告诉我们给定的REP值是否格式良好。或者,你可以把RI想为一个集合:它是定义AF的rep值得子集.
例如,下边的图表显示禁止重复字符的字符集代表,RI(“a”)=真,RI(“ac”)=真,和RI(“ACB”)=真的,但是RI(“AA”)=虚假和RI(“ABBC”)=假。符合REP不变的REP值显示在R空间的绿色部分,并且必须映射到A空间中的抽象值。违反REP不变的REP值显示在红色区域,在A空间中没有等效的抽象值。
REP不变量和抽象函数都应该记录在代码中,就在REP本身的声明旁边:
public class CharSet {
private String s;
// Rep invariant:
// s contains no repeated characters
// Abstraction function:
// AF(s) = {s[i] | 0 <= i < s.length()}
...
}
关于抽象函数和REP不变量的一个常见混淆是,它们是由REP和抽象值空间的选择决定的,甚至是由抽象值空间单独决定的。如果是这样的话,那就没什么用了,因为他们会说一些多余的东西,这些东西已经在其他地方找到了。
下图的实例就是很好的规范RI:
而对于AF:
每个抽象值都由某个REP值映射到。(满射) 实现抽象类型的目的是支持对抽象值的操作。那么,我们大概需要能够创建和操作所有可能的抽象值,因此它们必须是可表示的。
一些抽象值由多个REP值映射到。(未必单射)之所以会出现这种情况,是因为表示不是一个严格的编码。将无序字符集表示为字符串的方法不止一种。
并不是所有的REP值都被映射。(未必双射)在这种情况下,字符串“ABBC”没有映射,因为我们已经决定REP字符串不应该包含重复的字符串。这将使我们能够终止remove方法,因为我们知道最多只能有一个实例。