2008-11-20 37 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中,您可以更轻松地实现撤消/重做。 (执行一个未执行以及执行)