当我想要创建的类型每个都有不同的输入参数时,我可以使用工厂模式吗?

时间:2012-01-25 17:30:55

标签: c# .net design-patterns factory

在我的Windows窗体项目中,我有一个父窗体,它创建其他用户控件,然后放在TabControl上。我的问题是父表单中的代码变得非常大而且难以管理。

在我的父表单中,我的方法如下:

public SubControl1 CreateSubControl1(Guid ID, Info userInfo, bool populate)
public SubControl1 CreateSubControl1(Guid ID, Info userInfo, bool populate, StateType1 state)

public SubControl2 CreateSubControl2(Guid ID, Info userInfo, bool populate, String dataFile, String dataFile2, )
public SubControl2 CreateSubControl2(Guid ID, Info userInfo, bool populate, String dataFile, String dataFile2,  StateType2 state)

private SubControl3 CreateSubControl3(Guid ID, Info userInfo, bool populate, String dateFile)
private SubControl3 CreateSubControl3(Guid ID, Info userInfo, bool populate, String dateFile,  StateType3 state)

private SubControl4 CreateSubControl4(Guid ID, Info userInfo, bool populate, WorkingFolder wf)
private SubControl4 CreateSubControl4(Guid ID, Info userInfo, bool populate, WorkingFolder wf, StateType4 state)

目前,根据我想要创建的SubControl(1-4),我调用相应的CreateSubControlX方法。现在这个工作正常,但是我确信有更好的方法可以将所有创建代码收集到某种工厂类中。

但是,因为我的每个派生类型,输入参数略有不同,我想知道如何做到这一点?我应该创建一个“简单”工厂,它具有一般Create方法,该方法接收所有可能类型的参数和类型(以区分创建哪个SubControl 1到4)。然后,我可以为我不想设置的任何参数使用null。这对我来说似乎是一个坏主意。

E.g。 ControlFactory.Create(ID, userInfo, false, null, null, null, SubControlType1)

BaseControl是所有类型控件的基类,例如SubControl1SubControl4

任何人都可以提供任何帮助吗?

4 个答案:

答案 0 :(得分:4)

无论你做什么,都不要创建一个带有bezillion参数的mega方法。它使代码变得不可读,并且这使得必须编写代码来调用该方法(包括您)的人生活困难。

我的意思是真的。看看这个方法调用并告诉我它的作用:

 ControlFactory.Create(ID, userInfo, false, null, null, null, SubControlType1)

你做不到。有三个null args和一个true / false,它是不可读的,不可维护的代码。

制作多个重载或类似的命名方法,这些方法与您可以制作的方法一样具体。对于经常使用的方法,我会考虑通过创建两个方法来消除其中一个布尔args,一个硬编码为True case,另一个硬编码为False case。这些调用一个通用的内部函数,它采用布尔arg进行代码共享,但不希望外部使用者使用它。您总是希望最频繁执行的操作要求完成短路径 - 在代码执行方面以及到达目的地所需的击键方面。

创建易于使用的方法(API)的途径是减少参数的数量,使用描述性的类型(枚举优于布尔值),以及通过代码完成工具提示帮助发现的方法和参数名称。每次你反对这个口头禅,你都会为自己和其他人创造大量的额外工作和复杂性。

答案 1 :(得分:1)

您的参数列表正在增长到引入参数对象可能合理的程度。从长远来看,引入这种对象可能会使工厂模式更易于维护。

BaseClass Create( ParameterObject parameterObject )

答案 2 :(得分:0)

您创建实例的类型可以采用任何类型和数量的参数,只要工厂也知道这些参数,以便它可以在构造期间传递它们。

为了使其可维护,通常最好为1种类型提供1个抽象工厂。因此,对于使用不同SubControl类型的情况,您可能最好为每个SubControl使用单独的工厂。

答案 3 :(得分:0)

如果您使用.Net 4,您可以使用非常好的命名参数:)

public CreateSubControl(Guid ID, Info userInfo, bool populate, String dateFile = null, String dataFile2 = null, StateType1 statetype1 = null, StateType2 statetype2 = null)
{
    // Do stuff with those variables here

}

并称之为(仅举几例):

CreateSubControl(id, userinfo, populate, dateFile = "blah", statetype2 = somethinghere)
CreateSubControl(id, userinfo, populate, dateFile = "blah", dateFile2 = "blah2", statetype3 = somethingelsehere)

但我确实同意它难以阅读此代码或告诉您应该做什么以及为什么有这么多类似的类型。也许你需要一个界面?