对于AF、RI、Safety from rep exposure的理解
AF、RI、Safety from rep exposure
AF、RI、Safety是从开始做实验就接触的一个东西,但是只是知道他们大概是什么,上课时也将了关于这个的内容,但是始终没有一个很好的理解,今天来简要的讲述一下我的理解
AF
首先AF的全称是:Abstraction function(抽象函数),根据函数我们就可以联想到映射,AF就是类似于一个映射
其中A是抽象值构成的空间,是client应该观测到的值,R是创建的类,但是可能有些类并不满足client的要求,所以AF不一定是R中的每个元素都有对应的A中的元素,但是只要是client应该得到的元素都应该有一个类或多个类对应,所以AF一定是满射。
总结起来就是:AF一定是满射,不一定是单射,也就不一定是双射。
RI
RI全称是:Representation invariant(表示不变量),对于表示不变量,我认为通俗一点的理解就是client的要求,即什么样的类才是符合要求的,还用这张图为例:
“abbc”没有对应的A中的元素,那么“abbc”就是一个不满足RI的元素,一个满足这个图的RI就是“不可以有重复的字母”
Safety from rep exposure
这个就很易于理解了,就是防止表示泄露的方法,在我的上一篇博客中已经介绍来了可变类与不可变类,如果不了解,可以访问我的上一篇博客:Java中的可变类与不可变类
不可变类没什么可以泄露的了,因为不可变类只有getter才有可能获得类中的变量,但是由于是不可变类,即使获得了也无法修改
可变类是应该要注意的,因为可变类中getter到的变量可以直接对其修改,而且类中变量指向的地址的内容会被修改,所以这就是一个表示泄露,应对此情况的方法是,getter得到的不应该是类中的变量,而是类中变量的一个副本,这也就是常说的防御式拷贝。
讲述了这些,相信大家已经对AF、RI、Safety form rep exposure有了一定的了解,下面给出一个具体的例子,来更进一步的理解,这里就采取上图中的例子:
public class Example {
private final String str;
/*
* AF:将合法的字符串,转化为字符集(有序)的形式
*
* RI:字符串长度大于等于0,并且每个字符仅最多仅可以出现一次
*
* Safety from rep exposure:无,String是不可变数据类型
*/
public void checkRep() {
Set<Character> set = new HashSet<Character>();
for(int i = 0; i < str.length(); i ++) {
assert !set.contains(str.charAt(i));
set.add(str.charAt(i));
}
}
public Example(String str) {
this.str = str;
}
public void trans() {
checkRep();
List<Character> list = new ArrayList<Character>();
for(int i = 0; i < str.length(); i ++) {
list.add(str.charAt(i));
}
Collections.sort(list);
System.out.print("{");
for(int i = 0; i < list.size() - 1; i ++) {
System.out.print(list.get(i) + ", ");
}
System.out.println(list.get(str.length() - 1) + "}");
}
public String getter() {
return this.str;
}
}
public class tryness {
public static void main(String[] args) throws Exception {
Example e = new Example("acb");
e.trans();
}
}
运行结果:
{a, b, c}
此篇文章只是我个人理解,如果有错误欢迎指出,感谢阅读!