Factory method for generic interface
I think this code is mortally wounded but would like some opinions before I take a new approach.
I am writing a factory method for the following interface.
public interface ITransformer<I, O>
{
O Transform(I input);
}
Here is a possible implementation of the interface
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;
}
}
The first factory I did looks like this
static class Tr开发者_开发技巧ansformerFactory
{
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;
}
}
}
But I have to know the exact types when I call the factory method so it seems less than ideal.
ITransformer<Car, Truck> transf = TransformerFactory.GetTransformer<Car, Truck>();
I have also toyed with the following, but I'm afraid this may be a gross misuse of the dynamic keyword.
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;
}
}
}
But it does allow me to get the factory syntax that I want.
dynamic transf = TransformerFactory2.GetTransformer(car, truck);
I've also considered the first option but calling the factory method with reflection so I could dynamically assign the type variables.
Ultimately, I would like the entire "transform" process to be contained in one reusable method and just implement new transformers when needed but I'm not there yet.
Is there a better or safer approach for this kind of situation?Thanks for reading.
This is way off topic if you are interested in exploring OOP and Patterns but this specific example you are describing can be fairly neatly described using Func<I,O>
delegates.
e.g.
var car = getSomeCar();
car.select(c => new Truck{
:
:
});
And you define select
as a generic extension method on I
e.g.
public static O select<I,O>(this I input, Func<I,O> project)
{
return project(input);
}
Just a thought.
Edit
Just tested this and it should work fine :)
Renamed transform
to select
to highlight the similarity to the Linq operator.
精彩评论