改进泛型类型检查(factory-ish模式)以更加面向SOLID?

时间:2012-03-27 19:42:23

标签: c# solid-principles

我想知道如何更好地编写这样的代码,以便它利用更多的SOLID原则......

public static T TransformXmlToEntity<T>(string xml) {
    if(typeof(T) == typeof(EntityA)) {
        return TransformXmlToEntityA(xml);
    } else if (typeof(T) == typeof(EntityB)) {
        return TransformXmlToEntityB(xml); 
    }
}

private static T TransformXmlToEntityA(string xml) {
    var entityA = new EntityA();
    //mapping occurs; sudo code
    entityA.Person = xml.element(Person).value;
    ...
    return entityA;
}
private static T TransformXmlToEntityB(string xml) {
    var entityB = new EntityB();
    //mapping occurs; sudo code
    entityB.Product = xml.element(Product).value;
    ...

    return entityB;
}

这段代码感觉不对。但我想不出如何做得更好。

2 个答案:

答案 0 :(得分:3)

转化地图怎么样?

private static Dictionary<Type, Func<string,object>> conversionMap = new Dictionary<Type, Func<string,object>> 
{ 
    {typeof(EntityA), TransformXmlToEntityA},
    {typeof(EntityB), TransformXmlToEntityB},
    // ....
}

public static T TransformXmlToEntity<T>(string xml) 
{
    return (T)conversionMap[typeof(T)](xml);
}

答案 1 :(得分:0)

我会做这样的事情

interface IXmlTransformer
{ 
   string Transform(object entity);
}

class EntityAXmlTransformer : IXmlTransformer
{
    string Transform(object entity) { /* implementation */ }
}

class EntityBXmlTransformer : IXmlTransformer
{
    string Transform(object entity) { /* implementation */ }
}

// ideally an IoC container would do this - but here is a naive factory implementation
class XmlTransformerFactory
{
     private static readonly Dictionary<Type, IXmlTransformer> transformers = new Dictionary<Type, IXmlTransformer>
     {
          { typeof(EntityA), new EntityAXmlTransformer() },
          { typeof(EntityB), new EntityBXmlTransformer() }
     }

     public IXmlTransformer Get<T>()  // could be static
     {
         IXmlTransformer transformer;

         if (!transformers.TryGetValue(typeof(T), out transformer))
         {
             return null;
         }

         return transformer;
     }
}

然后你可以这样做:

var factory = new XmlTransformerFactory();

var transformerA = factory.Get<EntityA>();
string xmlA = transformerA.Transform(entityAInstance);

var transformerB = factory.Get<EntityB>();
string xmlB = transformerB.Transform(entityBInstance);