2008-11-20 36 views
3

我以前曾經遇到這個問題很多次,而且我從來沒有遇到過一個我感覺良好的解決方案。爲對象類型選擇正確的視圖

比方說,我有一個事務基類和兩個派生類AdjustmentTransaction和IssueTransaction。

我有一個UI中的事務列表,每個事務都是具體類型AdjustmentTransaction或IssueTransaction。

當我選擇一個事務,並單擊「編輯」按鈕,我需要決定是否顯示AdjustmentTransactionEditorForm或IssueTransactionEditorForm。

問題是我該如何做到這一點,而不必在所選事務的類型上使用switch語句? switch語句有效,但感覺很糟糕。我覺得我應該能夠以某種方式利用Transaction和TransactionEditor之間的並行繼承層次結構。

我會對我的交易中EditorForm屬性,但是這是我的UI花生醬與我的模型巧克力可怕的混合。

在此先感謝。

回答

1

您需要將您的「EditorForm」映射到某個事務處。你有幾個選項:

  • 一個switch語句...像你一樣,我覺得這個很臭,而且規模很小。
  • 基本事務類中的抽象「EditorForm」屬性,可以更好地進行縮放,但關注點分離較差。
  • A Type - >表單映射器在您的前端。這比例相當好,並保持良好的分離。

在C#中,我會實現一個類型 - >表映射這樣的:

Dictionary <Type,Type> typeMapper = new Dictionary<Type,Type>(); 
typeMapper.Add(typeof(AdjustTransaction), typeof(AdjustTransactionForm)); 
// etc, in this example, I'm populating it by hand, 
// in real life, I'd use a key/value pair mapping config file, 
// and populate it at runtime. 

然後,單擊編輯時:

Type formToGet; 
if (typeMapper.TryGetValue(CurrentTransaction.GetType(), out formToGet)) 
{ 
    Form newForm = (Form)Activator.CreateInstance(formToGet); 
} 
+0

我認爲這對我很有用,而且分機。配置文件建議從你和比爾K將真正使這個很好。謝謝! – 2008-11-20 19:54:44

0

難道我錯過了什麼的問題?我只是問,因爲顯而易見的OO答案是:多態性

只需執行Transaction.editWindow()(或者您想調用它), 用AdjustmentTransaction和IssueTrasaction中的方法覆蓋所需的功能。調用element.editWindow()然後爲你打開正確的對話框。

+0

他想要將UI與交易狀態類分開。 – FlySwat 2008-11-20 19:35:17

1

您可能不希望將其綁定到繼承樹 - 稍後當您稍做要求更改時,這會將您綁定得很好。

該關係應該在外部文件的某處指定。描述關係的東西:

Editing AdujustmentTransaction = AdjustmentTransactionEditorForm 
Editing IssueTransaction = IssueTransactionEditorForm 

隨着解析的一點點,比我在這裏使用了一些更好的語言,這個文件可能會變得非常普遍和可重複使用的 - 如果需要的話,你可以重用的形式爲不同的對象,或者更改用於編輯對象的表單而不需要太多的努力。

(你可能想命名爲「喬」用戶使用「JoeIssueTransactionEditorForm」來代替,這可以很容易地加工成你的「語言」)

這主要是依賴注入 - 你大概可以使用Spring來解決這個問題更籠統地說。

+0

我真的很喜歡你的評論,關於不綁定inh。樹,這在你描述的場景中很有意義。 – 2008-11-20 19:51:26

0

到詞典/配置文件的方法另一種方法是

1)來定義一個接口,用於每個交易編輯器。

2)在您的EXE或UI組件中,每個表單都會向創建單個事務的程序集註冊自己。

3)控制註冊的類應該是一個單例,所以你沒有多個表單實例。

3)當創建一個單獨的事務時,它從註冊對象中提取正確的表單變量併爲其分配一個內部變量。

4)當Edit方法被調用時,它只是使用內部方法的Show方法來啓動將導致顯示該Transacton編輯器的調用鏈。

這消除了對配置文件和字典的需求。它繼續將UI與對象分開。另外,您不需要任何開關語句

不利之處在於除了窗體本身外,還必須爲每個窗體編寫接口。

如果您有不同類型的編輯器(數十個)大量然後在這種情況下,我建議您使用命令模式

您有包含dictonary喬納森推薦一個主命令。該命令輪流使用該雙字符來執行其他命令中的一個,該命令用正確的對象調用正確的形式。這些形式繼續與對象本身分離。這些表單駐留在Command程序集中。另外,您不必更新EXE以僅添加另一個編輯器,即Command組件。最後,通過將命令放入Command中,您可以更輕鬆地實現撤消/重做。 (執行一個未執行以及執行)