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 ofForwardingMap.putAll
. Be careful to override every method whose behavior must be changed,and make sure that your decorated collection satisfies its contract.
所以,如果我理解这一切,番石榴就不是一个很好的例子.