我有一个(Java)类,WindowItem,有一个问题:其中一个方法不是线程安全的。我无法修复WindowItem,因为它是外部框架的一部分。所以我想我为它实现了一个装饰器,它在所讨论的方法上有一个“同步”关键字。最终方法的Java类装饰器
装饰器扩展WindowItem并且还包含WindowItem。在Decorator模式之后,我在Decorator中创建了调用它所包含的WindowItem的方法。
但是,WindowItem有几个最终方法,我不能在装饰器中重写。这打破了装饰者的透明度。让我们更加明确:
public class WindowItem {
private List<WindowItem> windows;
public Properties getMethodWithProblem() {
...
}
public final int getwindowCount() {
return windows.size();
}
}
public class WindowItemDecorator extends WindowItem {
private WindowItem item;
public WindowItemDecorator(WindowItem item) {
this.item = item;
}
# Here I solve the problem by adding the synchronized keyword:
public synchronized Properties getgetMethodWithProblem() {
return super.getMethodWithProblem();
}
# Here I should override getWindowCount() but I can't because it's final
}
在我自己的代码,每当我有什么地方传递WindowItem,我在一家装饰包裹它首先:新WindowItemDecorator(项目) - 和线程安全问题就消失了。但是,如果我的代码在WindowItemDecorator上调用getwindowCount(),它将始终为零:它在超类上执行getWindowCount(),而不是“item”成员。
所以我会说WindowItem的设计(它具有公共final方法的事实)使得不可能为这个类创建一个装饰器。
这是正确的,还是我错过了什么?
在这种情况下,我可能会保留装饰器中窗口列表的副本,并保持同步,然后getWindowCount()的结果将是正确的。但在这种情况下,我更喜欢叉和修补框架...
你的第一个反射是正确的,但最终的方法使它无法覆盖它们。你必须传递/操作“WindowItem”类型的对象吗?如果不是,则不必使用装饰模式。您可以使用组合并通过将它们包装到不扩展WindowItem但通过组合使用实例的新类中来控制对WindowItem的最终方法的调用。 – Ushox 2012-08-02 10:08:02