我有一个(Java)类 WindowItem,它有一个问题:其中一种方法不是线程安全的。我无法修复 WindowItem,因为它是外部框架的一部分。所以我想我为它实现了一个装饰器,它在有问题的方法上有一个“同步”关键字。
装饰器扩展了 WindowItem 并且还将包含 WindowItem。按照装饰器模式,我在装饰器中创建调用它包含的 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 时,我首先将它包装在一个装饰器中:new WindowItemDecorator(item)——线程安全问题就消失了。但是,如果我的代码在 WindowItemDecorator 上调用 getwindowCount(),它将始终为零:它在超类而不是“item”成员上执行 getWindowCount()。
所以我想说 WindowItem 的设计(事实上它有公共的 final 方法)使得为这个类创建一个装饰器是不可能的。
这是正确的,还是我错过了什么?
在这种情况下,我可以在装饰器中保留窗口列表的副本,并使其保持同步,然后 getWindowCount() 的结果将是正确的。但在那种情况下,我更喜欢分叉和修补框架......