今天在看struts2的源代码的时候,发现一个很有趣的东西,突然联想到之前看过Google的Guava,Guava当中有不可变的集合,这是很好补充了jdk中的不可变集合。本次重点不是guava,只是稍微提及一下,如需要了解,请参考其他读物。那么本次的说明只是在看那个源代码的时候给人一种诧异的感觉,也突然相对最近工作中可以应用这种写法。
今天看到的内容是:在代码的前大部分处理逻辑后会返回一个List列表,这个List是整个方法的结果,那么其return值是这样写的:Collections.unmodifiableList(list);其中list为之前的逻辑计算出来的一个List,另外在这段代码最后是不需要对List进行其他处理的。其中JDK对unmodifiableList的描述是:返回指定列表的不可修改视图。注意是视图。详细解释为:此方法允许模块为用户提供对内部列表的“只读”访问,在返回的列表上执行的查询操作将“读完”指定的列表。试图修改返回的列表(不管是直接修改还是通过其迭代器进行修改)将导致抛出 UnsupportedOperationException。其实在我们的日常开发的逻辑当中,绝对缺少不了查询这个功能,而查询这个功能实际上需要返回的就是一个视图,如果需要修改这个视图,可以在此基础上新建视图,这其实也是确保显示数据与数据库的数据一致性。当然,我们程序员可以一定程度保证显示的内容不可以被修改,但是为什么不使用unmodifiableList而需要多次一举呢?
JDK1.6中一共给予了三个这种类型的集合,分别是unmodifiableList, unmodifiableMap,unmodifiableSortedMap。很明显这些都代表了什么意思,但是他们都是集合,如果想使用更多的此类型的集合,可以研究一下Guava,会有更多意外的惊喜。
在《重构——改善既有代码的设计》一书中,有一种重构手法叫Encapsulate Collection(封装集群),其大概意思是:一个类中,除了基本的域字段外,还包括集合字段,如Set,List等,这些集合字段不要设计成我们常见的getter和setter,替换的是:对于getter,可以返回一个该集合的一个只读副本,而对于setter,其实包括两种操作:删除和添加,删除就采用集合删除的方式,而添加类似于往集合中添加该集合对于的类型。总的来说是两种方法被三个方法替换了,三个方法中其中的getter方式,是返回一个只读副本,另一种含义就是不可变的集合副本,于是可以使用unmodifiableList等,其中这样重构的一个好处就是可以降低集合的拥有者(拥有该集合的对象的类)和用户之间的耦合度,注意是降低。其实仔细想想,不可变的集合就是不顾一切,没有任何原则地把结果丢给你,并且给你的东西在操作性上限制了最小化,因此来达到降低两者之间的耦合度。所以某种程度上感觉使用不可变集合就是将一种东西与另一种东西解耦合,降低彼此之间的关联的集合。