通用接口的工厂方法

时间:2011-03-30 20:28:51

标签: c#-4.0 factory-pattern

我认为这段代码受了致命伤,但在采取新方法之前需要一些意见。

我正在为以下界面编写工厂方法。

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);

我还考虑了第一个选项但是用反射调用工厂方法,所以我可以动态地分配类型变量。

最终,我希望将整个“转换”过程包含在一个可重复使用的方法中,并在需要时实现新的变换器,但我还没有。 对于这种情况,有更好或更安全的方法吗?

感谢阅读。

1 个答案:

答案 0 :(得分:0)

如果您有兴趣探索OOP和模式,这是偏离主题的,但您正在描述的这个具体示例可以使用Func<I,O>代理进行相当整齐的描述。

e.g。

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

您可以在select

上将I定义为通用扩展方法

e.g。

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

只是一个想法。

修改

刚试过这个,应该可以正常运行:) 将transform重命名为select以突出显示与Linq运算符的相似性。