我有一個(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