2009-08-25 118 views
0

我目前正在使用Oracle的ADF Faces JSF實現用於表示層的遺留系統。系統依賴於規則引擎,根據用戶與它們的交互或輸入的值,使某些表單元素成爲必需,禁用甚至突出顯示。添加功能:子類與修飾器

在目前的階段,應用程序是「工作」的,有點。當前實現處理規則引擎和前端的更新是不是很優雅,有一個寬敞的集合,如果類似的語句:

if(screenObj instanceof CoreInputText) { 
    ((CoreInputText) screenObj).setDisabled(true); 
} 

進來,我們也有這樣的混合我們自己的對象複雜化一體設置不共享一個共同的祖先,從而消除我們做這樣的選擇:

((CommonAncestor) screenObj).setDisabled(true); 

的問題是,它是否會成爲值得返工代碼的這一部分更清潔,更清晰。由於大多數屏幕元素都是ADF Faces元素,因此我們不能/允許更改其祖先以添加其他方法。

代碼更改的目標有兩個方面:清理較舊的代碼並改進代碼庫,以便添加新的元素或控件不會導致較大的代碼更改(特別針對if語句存在在許多地方)。

所以,如果我們繼續這種改變,這將是實現我們要找的更好的選擇?爲所有元素創建子類(每次我們使用另一個預先存在的控件時都需要一個新類)或實現裝飾器模式?我唯一關心的是裝飾器,它仍然需要爲每個附加元素進行代碼更改。這兩個選項似乎都會減少代碼更改,因爲包含這些if塊的多個方法不需要更新。

歡迎任何關於處理子類和裝飾器以外的情況的輸入!

回答

1

儘管它們沒有共同的祖先,但您並未指定它們是否具有通用方法。如果他們這樣做了,那麼可能只需在運行時使用一個只調用該方法的代理來放入一個接口,以便擁有一個通用類型。這當然是一種裝飾器,並且由於它使用了反射,它可能太慢(雖然可能不是),但它具有任何新對象的優點,只需實現正確的方法簽名(或者可以讓新對象實現接口,併爲舊對象保留代理並有條件地在工廠方法中創建代理,以檢查對象是否需要它)。另外,如果這是一個真正的setter,你可以使用來自apache的BeanUtils,並將其設置爲一個名爲disabled的屬性。

編輯:鑑於他們沒有相同的方法,一些代碼將不得不被添加每次添加一個新的對象,除非你至少可以控制前進新的對象將有一個定義的接口。話雖如此,如果你能順利地沿着反射路線走,你可以創建一個類到方法的映射(假如這些方法都採用布爾值 - 如果必須的話,你甚至可以強制你的方法),並查找對象在地圖中。這樣,當你引入一個新的對象時,你只需要在地圖上添加一個條目。

但是,我的意願是避免這一點,因爲這似乎反映得太過分了。它使得方法名稱很難重構,並且IDE不可能發現它們在該上下文中被使用。我認爲裝飾者是第一眼看到的正確選擇,因爲在任何其他考慮的情況下,組合應該首選繼承,並且會爲正在發生的事情制定更明確的代碼路徑,從長遠角度改善維護。

+0

對不起,我應該提到這一點。不,他們沒有一個共同的方法。我也希望爲這兩種方法增加新的方法;像突出(布爾),這將只是設置一些屬性。 – doomspork 2009-08-26 02:42:33