根据使用C#传递给函数的参数创建不同对象的实例

时间:2014-12-10 13:21:56

标签: c# design-patterns

我有基类FactoryBO,它有一个创建不同对象实例的方法。

public class FactoryBO
{
    //ctor
    public FactoryBO()
    {
    }

    public T CreateObject<T>(string BusinessObjectName)
    {
        if (string.IsNullOrEmpty(BusinessObjectName))
            return default(T);

        object valueObj = null;

        switch (BusinessObjectName.ToLower())
        {
           case "temporary registration": { valueObj = new TemporaryDriverRegistrationBO(); break; }
            case "driver registration": { valueObj = new TemporaryDriverRegistrationBO(); break; }            }

        return (T)valueObj;
    }

    public virtual SqlParameter[] GenerateQuery(params object[] StoredProcedureParameters)
    {
        return null;
    }
}

FactoryBO有2个派生类,它覆盖了FactoryBO中的虚方法。

public class TemporaryDriverRegistrationBO : FactoryBO
{
    public override SqlParameter[] GenerateQuery(params object[] StoredProcedureParameters)
    {
         //some Code
    }
}

 public class DriverRegistrationBO : FactoryBO
 {
      public override SqlParameter[] GenerateQuery(params object[] StoredProcedureParameters)
    {
         //some Code
    }
 }

现在,如果我执行下面的代码,它给了我&#34; TemporaryDriverRegistrationBO&#34;的对象。

   object fbo = new FactoryBO().CreateObject<object>("temporary registration");
   SqlParameter[]  xx = ((FactoryBO)(fbo)).GenerateQuery()

我是以错误的方式做的?这是否遵循任何设计模式?

关于功能的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

在您的实施中,您不会限制代码的用户使用T传递的内容。这听起来像是个问题,请考虑使用以下类型参数限制where T: FactoryBo, new()。 然而,这不是你想要的。我建议创建一个函数字典,将某个业务对象名称映射到适当类的构造函数:

public class FactoryBO
    {
        public static Dictionary<string, Func<FactoryBO>> objects =
                new Dictionary<string, Func<FactoryBO>>
                    {
                            {"temporary registration", () => new TemporaryDriverRegistrationBO()},
                            {"driver registration", () => new DriverRegistrationBO()}
                    };

        public static FactoryBO CreateObject(string businessObjectName)
        {
            if (string.IsNullOrWhiteSpace(businessObjectName))
            {
                return new FactoryBO();
            }

            Func<FactoryBO> objectCtor = null;
            objects.TryGetValue(businessObjectName.ToLower(), out objectCtor);

            return objectCtor != null ? objectCtor() : new FactoryBO();
        }

        public virtual SqlParameter[] GenerateQuery(params object[] StoredProcedureParameters)
        {
            return null;
        }
    }

在我的实现中,我将返回一个基类实例 - FactoryBO,以防在词典中找不到该条目。这与您为空字符串参数返回default(T)的行为略有不同(这会为引用类型返回null)。

http://msdn.microsoft.com/en-us/library/xwth0h0d.aspx

答案 1 :(得分:0)

在您的交换机中,您返回类型,而不是这些类型的实例。

替换:

switch (BusinessObjectName.ToLower())
{
    case "temporary registration": { valueObj = typeof(TemporaryDriverRegistrationBO); break; }
    case "driver registration": { valueObj = typeof(DriverRegistrationBO); break; }
}

使用:

switch (BusinessObjectName.ToLower())
{
    case "temporary registration":
        valueObj = new TemporaryDriverRegistrationBO();
        break;
    case "driver registration": 
        valueObj = new DriverRegistrationBO();
        break;
}

假设您的对象具有默认构造函数。

无论如何,你的通用参数在这里没用,你创建的对象也不必扩展FactoryBO

答案 2 :(得分:0)

这似乎不是对泛型的有效使用。看起来你真正想要的是多态性,你不需要泛型来利用多态性。

尝试一下(请注意,我已将该方法设为静态,因为它不使用任何实例变量):

public static FactoryBO Create(string BusinessObjectName)
{
    if (string.IsNullOrEmpty(BusinessObjectName))
    {
        return null;
    }

    FactoryBO valueObj = null;

    switch (BusinessObjectName.ToLower())
    {
        case "temporary registration": 
           valueObj = new TemporaryDriverRegistrationBO(); 
           break;
        case "driver registration": 
           valueObj = new DriverRegistrationBO(); 
           break;
    }

    return valueObj;
}

然后你可以这样做:

FactoryBO fbo = FactoryBO.Create("temporary registration");