软件构造随笔三

在回看mit阅读材料13之后,这篇随笔分享一些我在这篇阅读材料中的收获。

还是在开头感谢李秋豪学长的翻译版本。

这篇阅读材料向我们介绍了几个有关ADT设计的思想和概念,:
不变量(invariants)
表示暴露(representation exposure)
抽象函数(abstraction functions)
表示不变量(representation invariants)

我在之前java编程时确实只会关注一个ADT是否正确完成了功能,不会考虑其他的问题。
这种做法在我们完成一些小程序时没有问题,但当涉及到大型项目,里面有几十个,甚至几百个ADT时,这样的做法就不再适合了。

1:不变量:

不变量是一种属性,它在程序运行的时候总是一种状态,一旦一个不变类型的对象被创建,它总是代表一个不变的值,我们希望这个值在程序运行时始终保持不变。而当不变量被破坏时,我们的程序功能也很有可能会被破坏。

以阅读材料中的例子来说:
软件构造随笔三

Tweet是个不可变类型,即一旦被创建,author, message, 和 date都不能被改变,但是:软件构造随笔三

在这样操作下,author就被改变了,如过允许这样的改动,之后的代码就很有可能会错误。这样的操作就会导致表示暴露(Rep exposure)。

2.解决方法:
2.1:首先我们可以这样处理:
软件构造随笔三
将成员变量变为private 和 final类型,private 表示这个区域只能由同类进行访问;而final确保了该变量的索引不会被更改,对于不可变的类型来说,就是确保了变量的值不可变。

但这里例子中还有一个问题,Date为可变类型,所以工作还为结束

(在这里插入一些今天习题课的内容:例如:有成员变量Set a,其中Person为可变类型,而某函数会返回a。
为了保证表示不变量,我们首先会想到保护性复制,但由于Person类还是可变的,所以还要使用java中的Collections.unmodifiableList()来处理)
2.2:
当使用如下操作时就会出现错误:
软件构造随笔三
错误原因如快照图所示:
软件构造随笔三

这样的话方法中的改变会导致成员变量的改变,导致错误。

解决方法就是要做保护性复制:
软件构造随笔三
这样不论在方法中改变改变都不会改变原来的成员变量。

2.3:下面是一种不常见的情况,在阅读材料前确实没有考虑过这种情况
软件构造随笔三

出错的原因是,所有的Tweet中的date的执向相同。不过个人感觉这里的问题主要是Date date的处理出了问题,可以在循环中每次新new一个,而不是使用同一个date。当然也可以认为是Tweet类的构造器有漏洞。

在后者的理解下,改进如下:
软件构造随笔三

2.4:
除了上面的方法外,我们在设计时可以直接选用不可变类型如java.time.ZonedDateTime,然后直接加private,final就可以解决,或者我们还能使用Collections.unmodifiableList()来处理,不过缺点是Java不会在编译的时候对你对“不可变”列表的修改提出警告。

以上就是目前位置我常用的几种防止表示暴露的方法,以后要再学到新方法,会陆续添加。

以上内容如有错误,欢迎指正。