我认为这段代码受了致命伤,但在采取新方法之前需要一些意见。
我正在为以下界面编写工厂方法。
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 :(得分: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运算符的相似性。