有效的Java:转发类的安全性

前端之家收集整理的这篇文章主要介绍了有效的Java:转发类的安全性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有效的 Java第3版,第18项:优先于继承的组合描述了使用继承向类添加行为的问题:

A related cause of fragility in subclasses is that their superclass can acquire new methods in subsequent releases. Suppose a program depends for its security on the fact that all elements inserted into some collection satisfy some predicate. This can be guaranteed by subclassing the collection and overriding each method capable of adding an element to ensure that the predicate is satisfied before adding the element. This works fine until a new method capable of inserting an element is added to the superclass in a subsequent release. Once this happens,it becomes possible to add an “illegal” element merely by invoking the new method,which is not overridden in the subclass.

推荐的解决方案:

Instead of extending an existing class,give your new class a private field that references an instance of the existing class… Each instance method in the new class invokes the corresponding method on the contained instance of the existing class and returns the results. This is known as forwarding,and the methods in the new class are known as forwarding methods… adding new methods to the existing class will have no impact on the new class… It’s tedious to write forwarding methods,but you have to write the reusable forwarding class for each interface only once,and forwarding classes may be provided for you. For example,Guava provides forwarding classes for all of the collection interfaces.

我的问题是,风险是否仍然存在方法也可以添加到转发类,从而打破子类的不变量?像Guava这样的外部库如何在转发类时采用更新的方法而不会冒客户端的完整性?

解决方法

默认的假设似乎是你是编写转发类的人,因此你可以控制是否有任何东西被添加到它.无论如何,这是使用组合而不是继承的常用方法.

Guava示例似乎是指the Forwarding Decorators,它们明确地设计为继承自.但它们只是帮助创建这些转发类更简单,而无需在接口中定义每个方法;它们明确地不会保护您免受将来可能需要覆盖的任何方法的影响:

Remember,by default,all methods forward directly to the delegate,so overriding ForwardingMap.put will not change the behavior of ForwardingMap.putAll. Be careful to override every method whose behavior must be changed,and make sure that your decorated collection satisfies its contract.

所以,如果我理解这一切,番石榴就不是一个很好的例子.

猜你在找的Java相关文章