是一个switch语句适用于工厂方法? C#(Is a switch statement app

2019-07-31 00:43发布

我想回到一个接口和一个switch语句,我想设置它。 这是一个不好的设计?

private IResultEntity GetEntity(char? someType)
    {
        IResultEntity entity = null;

        switch (someType)
        {
            case 'L': //life
                entity = new LifeEntity();
                break;
            case 'P': //property
                entity = new PropertyEntity();
                break;
            case 'D': //disability
                entity = new DisabilityEntity();
                break;
            case 'C': //credit card
                entity = new CreditCardEntity();
                break;
        }

        return entity;
    }

Answer 1:

我通常不介意switch语句在一家工厂,提供我所能组和控制所有的,我想我厂提前创建派生类。

有时,也许用户创建的插件可能希望它自己的类添加到该交换机列表,然后SWICH声明是不够的。

我发现这个好更多的一些信息源上创造一些更强大/通用的工厂类

一个很好的中间路线的方法,我通常采取的是保持一个静态字典<字符串类型>每个工厂类。

使用某种形式的人可以只“注册”自己的实现

Factories.TypeRegistration.StaticDictionary.Add("somekey",typeof(MyDerivedClass))

(或者更好的是,使用一个登记方法和隐藏StaticDictionary)

然后工厂已通过执行该表中查找创建实例一件容易的事:

Activator.CreateInstance(Factories.TypeRegistration.StaticDictionary["somekey"]);


Answer 2:

我不知道,你要在C#这可能性,但它仍然是最好有在工厂方法一个开关不是让所有的地方的开关。 在工厂方法,一个开关是可以容忍的 - 不过还好有它有据可查。



Answer 3:

我宁愿要实例在一个配置文件中的特定值的类型。 就像是:

<TypeMappings>
<TypeMapping名称= “生命” 类型= “Entities.LifeEntity,实体”/>
<TypeMapping名称= “属性” 类型= “Entities.PropertyEntity,实体”/>
<TypeMapping名称= “残疾” 类型= “Entities.DisabilityEntity,实体”/>
<TypeMapping名称= “的信用卡” 类型= “Entities.CreditCardEntity,实体”/>
</ TypeMappings>

里面你的方法,你可以再提取所有从配置文件中的注册,找到它的匹配和使用反射来实例化类型,如果没有找到注册,则抛出异常。

下面是一些示例代码:

namespace Entities
{

public interface IResultEntity
{
}

public class LifeEntity : IResultEntity
{
    public override string ToString()
    {
        return("I'm a Life entity");
    }
}

public class PropertyEntity : IResultEntity
{
    public override string ToString()
    {
        return("I'm a Property Entity");
    }
}

public class CreditCardEntity : IResultEntity
{
    public override string ToString()
    {
        return("I'm a CreditCard Entity ");
    }
}

public class DisabilityEntity : IResultEntity
{
    public override string ToString()
    {
        return("I'm a Disability Entity");
    }
}

}

    public static Entities.IResultEntity GetEntity(string entityTypeName,string fileName)
{
    XDocument  doc = XDocument.Load(fileName);
    XElement element = doc.Element("TypeMappings").Elements("TypeMapping")
                               .SingleOrDefault(x => x.Attribute("name").Value == entityTypeName);        

    if(element == null)
    {
        throw new InvalidOperationException("No type mapping found for " + entityTypeName);
    }   
    string typeName = element.Attribute("type").Value;
    Type type = Type.GetType(typeName);
    Entities.IResultEntity resultEntity = Activator.CreateInstance(type) as Entities.IResultEntity;
    if(resultEntity == null)
    {
        throw new InvalidOperationException("type mapping for " + entityTypeName +  " is invalid");
    }
    return resultEntity;
}

    public static void Main()
{
    try
    {
        Entities.IResultEntity result = GetEntity("life", @"c:\temp\entities.xml");
        Console.WriteLine(result);

         result = GetEntity("property", @"c:\temp\entities.xml");
        Console.WriteLine(result);

         result = GetEntity("disability", @"c:\temp\entities.xml");
        Console.WriteLine(result);          

         result = GetEntity("creditcard", @"c:\temp\entities.xml");
        Console.WriteLine(result);          

         result = GetEntity("foo", @"c:\temp\entities.xml");
        Console.WriteLine(result);      

    }
}

很多DI框架,让你提供,你可以查询基于元数据的接口多个注册。 看看这个链接上MEF如何做使用元数据出口。



Answer 4:

我不会说的一个不好的设计,虽然它可能相当严格。 延长的唯一途径是通过重新编译。



Answer 5:

我不觉得有什么错。 是的,switch语句是一个代码味道,但在我的书,他们在这种情况确定。 实际上,有没有别的你可以做些什么来实现这样的事情。



Answer 6:

它不坏,它几乎完全一样,在四个圣经本身的刚的例子(参数工厂方法)。

我曾经认为switch语句是一个代码味道,他们不是,他们有他们在任何面向对象语言的地方。



文章来源: Is a switch statement applicable in a factory method? c#