[size=large]封装性是面向对象程序设计的原则之一。保持良好的封装性需要在关注的程度和内存的消耗两方面付出代价。
克隆集合
返回对象的集合会使良好的封装性出现更多的问题。不论你是否在Collections API中使用legacy Hashtable和Vector对象或是他们的替代物,你都需要牢牢记住集合本身和他们的内容的可变性的级别。
对于返回集合要实现良好封装性的第一步就是要确保集合本身是不可变的或是无害可变的,就是说,它不更改对象的内容。最容易,但不是最有效的途径就是返回任一个集合的.clone(),如果你的类具有一个HashSet字符串对象,返回theSet.clone()而不是theSet本身就可以防止这个集合的recipient更改对象中名为theSet的集合的内容。
当你的集合包含类似于Strings的不可变对象时,克隆解决方案就足够了,但当被返回的集合包含可变对象的情况时,你就需要做一个深度克隆,在深度克隆过程中,所有集合中所包含的对象都与集合本身一起被克隆。使用深度克隆可以防止recipient更改对象内部存储的数据,但是它也会对内存和CPU造成很大的资源消耗。
返回不可变迭代器
返回一个产生被返回集合的内容的迭代器是实现不可变性的另一个途径。迭代器具有一套小型的给定方式,且只有一个方式可以变更源数据。此外,在 API之中的任何集合都可以很容易地获得一个Iterator。
将迭代器设置为不可变就可以取消remove方式。在迭代器例示时,使用由原集合返回的迭代器的一个匿名内部子类就可以轻松地实现这一点。你可以在表A中看到有关的例子。
然而,应该注意的是,这种方式只在源集合内部的对象是不可变时才适用,当他们是可变的时,你就需要进行深度克隆或是损失封装性。另一个问题是如果源集合在完全被消耗之前被修改,迭代器会带来令人生畏的ConcurrentModificationException。因为你没有办法来控制那一个调用者将使用返回的迭代器,所以你不得不确保只有当没有迭代器正在服务时才能做出源数据的改变。
物有所值吗?
保持良好的封装性需要在关注的程度和内存的消耗两方面付出代价。一些Java开发者根本没有注意到封装性,只要他们在一个小型项目中工作并与其他的开发者保持紧密的联系,这样的做法还是可行的。但是如果你正在编写的代码会被很多的开发者使用,例如一个图书馆,良好的封装性就是必须的了。一些由于类中数据的相互矛盾而造成的问题是很难诊断的,特别是这种矛盾的源头是类的可变性所导致的。[/size]
克隆集合
返回对象的集合会使良好的封装性出现更多的问题。不论你是否在Collections API中使用legacy Hashtable和Vector对象或是他们的替代物,你都需要牢牢记住集合本身和他们的内容的可变性的级别。
对于返回集合要实现良好封装性的第一步就是要确保集合本身是不可变的或是无害可变的,就是说,它不更改对象的内容。最容易,但不是最有效的途径就是返回任一个集合的.clone(),如果你的类具有一个HashSet字符串对象,返回theSet.clone()而不是theSet本身就可以防止这个集合的recipient更改对象中名为theSet的集合的内容。
当你的集合包含类似于Strings的不可变对象时,克隆解决方案就足够了,但当被返回的集合包含可变对象的情况时,你就需要做一个深度克隆,在深度克隆过程中,所有集合中所包含的对象都与集合本身一起被克隆。使用深度克隆可以防止recipient更改对象内部存储的数据,但是它也会对内存和CPU造成很大的资源消耗。
返回不可变迭代器
返回一个产生被返回集合的内容的迭代器是实现不可变性的另一个途径。迭代器具有一套小型的给定方式,且只有一个方式可以变更源数据。此外,在 API之中的任何集合都可以很容易地获得一个Iterator。
将迭代器设置为不可变就可以取消remove方式。在迭代器例示时,使用由原集合返回的迭代器的一个匿名内部子类就可以轻松地实现这一点。你可以在表A中看到有关的例子。
然而,应该注意的是,这种方式只在源集合内部的对象是不可变时才适用,当他们是可变的时,你就需要进行深度克隆或是损失封装性。另一个问题是如果源集合在完全被消耗之前被修改,迭代器会带来令人生畏的ConcurrentModificationException。因为你没有办法来控制那一个调用者将使用返回的迭代器,所以你不得不确保只有当没有迭代器正在服务时才能做出源数据的改变。
物有所值吗?
保持良好的封装性需要在关注的程度和内存的消耗两方面付出代价。一些Java开发者根本没有注意到封装性,只要他们在一个小型项目中工作并与其他的开发者保持紧密的联系,这样的做法还是可行的。但是如果你正在编写的代码会被很多的开发者使用,例如一个图书馆,良好的封装性就是必须的了。一些由于类中数据的相互矛盾而造成的问题是很难诊断的,特别是这种矛盾的源头是类的可变性所导致的。[/size]