重看rep exposure
最近在复习的时候,发现了一个以前一直没有掌握得很好的一个点,即表示泄露这一点。对于这一点的忽视也让我的Lab2的开发中出现了几个巨大的问题
首先什么是表示泄露,即ADT内部的某些数据可能会由于某些操作暴露给外部。 首先变值器是否是表示泄露?例如我的一个ADT开发为 地点, 设置了一个改变经纬度的变值器,这是否为表示泄露? 答案:不是,变值器设置的值发生了改变,这种肯定显然不是表示泄露。 那么获得器getter是否有表示泄露? 这就是我犯下的错误。 首先 返回一个immutable的类或者基本数据类型(int double)这些显然都不会有表示泄露。 例如下图:

若location为一个immutable的类,这里是没有表示泄露的。 这要涉及到java比较本质的一个点,这里我用C的思想进行解释。 location可以看作一个指向某个Location类的指针,对于一个immutable类,其内容显然是不变的,那么location这个指针的值(即所指对象)发生了改变吗? 答案是否,如果这个类内部没有setter(即让location)发生改变,那么location这个指针的值自创造以来就永远不会发生变化,其指向的值由于是immutable的,那么其内部内容就不会发生变化。由此,外部实际上是无法对该指针的值进行操作的,也就无法改变其内容。如果有如下代码:
Location p=xx.getLocation();
p.xxxxxx(这里因为是immutable的类,无法改变内部内容)
p=xxx2.getLocation();
很显然xx里面的location是没有被改变的。
那么如果类是mutable的,再次应用上述代码,就会很容易发现问题,p.xxxx这一步可能是某个setter,这样外部就绕过了xx类可能提供了的变值器,修改了ADT内部变量成员的值,这样就产生了表示泄露。
而我所做的实验里对于immutable不必多说,本身防范行就较好。而对于mutable类的防范性实际上不够,我们来看下面两段代码:


上述两个代码分别来自我的实验2与实验3。 第一张图就产生了表示泄露的问题,请看如下代码(假设图1的类为xxx)
Set<L> temp=xxx.vertices();
temp.add(p);
如果外部通过这样的方式调用了set的话,那么就会出现较大的错误,此时xxx类的vertices和外部代码中的temp指向的是同一个Set,即他们的指针值是一样的,由此产生了严重的表示泄露。
而第二张图就来自于我的Lab3,可以看到已经采用了防御性编程,这样返回值就是一个全新的list,即会产生一个新的指针值。这样就避免了rep exposure。
在个人感觉上,rep exposure的防范说简单也简单,说难也难,主要是是否能时时刻刻注意到这个问题。 Lab2的rep exposure我注意了某些问题,但是由于对java的不熟悉,不了解,对于元素集合这种稍微有点特殊的类的不了解,导致了我的lab2出现了rep exposure的问题,十分的可惜。这个问题是在开发lab3的过程中才发现的,想要去补救lab2已经太晚了。(所以我的lab3的报告挺强调rep exposure的,就是希望自己不要再犯同样的错误)。
浙公网安备 33010602011771号