2011-03-30 74 views
1

我认为这段代码受到了致命的伤害,但在采取新的方法之前,我想提出一些意见。通用接口的工厂方法

我正在为以下接口编写工厂方法。

public interface ITransformer<I, O> 
{ 
    O Transform(I input); 
} 

这里是一个可能实现的接口

public class CarToTruckTransformer : ITransformer<Car, Truck> 
{ 
    public Truck Transform(Car input) 
    { 
     Truck output = new Truck(); 
     output.Seats = input.Seats - 2; 
     output.BedSize = input.TrunkSize; 
     output.Gunrack = true; 
     return output; 
    } 
} 

第一家工厂我确实是这样的

static class TransformerFactory 
{ 
    public static ITransformer<I, O> GetTransformer<I, O>() 
    { 
     if (typeof(I) == typeof(Car) && typeof(O) == typeof(Truck)) 
     { 
      return (ITransformer<I, O>)new CarToTruckTransformer(); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 

,但我必须知道确切的类型时,我给工厂方法,所以它似乎不理想。

ITransformer<Car, Truck> transf = TransformerFactory.GetTransformer<Car, Truck>(); 

我也玩弄了以下内容,但恐怕这可能是对动态关键字的严重滥用。

public class TransformerFactory2 
{ 
    public static dynamic GetTransformer(VehicleBase input, VehicleBase output) 
    { 
     if (input.GetType() == typeof(Car) && output.GetType() == typeof(Truck)) 
     { 
      return (ITransformer<Car, Truck>)new CarToTruckTransformer(); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 

但它确实允许我得到我想要的工厂语法。

dynamic transf = TransformerFactory2.GetTransformer(car, truck); 

我也考虑过第一个选项,但用反射调用工厂方法,所以我可以动态地分配类型变量。最终,我希望整个“变换”过程被包含在一个可重用的方法中,并在需要时实现新的变换器,但我还没有。
这种情况有没有更好或更安全的方法?

感谢您的阅读。

+0

这是最好通过像Ninject这样的依赖注入库解决的问题。这些库允许您轻松地将具体实现绑定到接口,然后工厂可以在执行时轻松获得正确的实现。 – 2011-03-30 20:31:46

回答

0

如果您有兴趣探索面向对象和模式,但是您所描述的这个特定示例可以使用Func<I,O>代表进行相当整洁的描述,那么这就是主题。

例如

var car = getSomeCar(); 
car.select(c => new Truck{ 
    : 
    : 
}); 

你定义select作为一种通用的扩展方法上I

例如

public static O select<I,O>(this I input, Func<I,O> project) 
{ 
    return project(input); 
} 

只是一个想法。

编辑

只是测试这一点,它应该工作的优良:) 更名为transformselect突出的相似LINQ的运营商。

+0

我喜欢这个主意。我会试一试。 – johnnysim 2011-03-30 20:46:26