I have this builder in C# (naturally, the example is simplified):
class BusBuilder
{
Wheels mWheels = DefaultWheels;
int mRoute = 0;
public BusBuilder WithWheels(Wheels aWheels)
{
mWheels = aWheels;
return this;
}
public BusBuilder WithRoute(int aRoute)
{
mRoute = aRoute;
return this;
}
public Bus Build()
{
return new Bus { Wheels = mWheels, Route = mRoute };
}
}
It's used like this:
Bus bus =
new BusBuilder()
.WithWheels(someWheels)
.WithRoute(50)
.Build()
Now I want to extract a superclass that contains only some of the methods:
class VehicleBuilder
{
Wheels mWheels = DefaultWheels;
public VehicleBuilder WithWheels(Wheels aWheels)
{
mWheels = aWheels;
return this;
}
}
class BusBuilder : VehicleBuilder
{
...
}
The problem is that now I can't write
Bus bus =
new BusBuilder()
.WithWheels(someWheels)
.WithRoute(50)
.Build()
because WithWheels
returns a VehicleBuilder
rather than a BusBuilder
, and therefore does not define a WithRoute
method.
How would you design this?
The builder pattern is a bit of a pain when it comes to inheritance. You can do something like this:
class VehicleBuilder<T> where T : VehicleBuilder<T>
{
private T @this;
protected VehicleBuilder()
{
// Or pass it in as a constructor parameter
@this = (T) this;
}
public T WithWheels(...)
{
return @this;
}
}
Then:
class BusBuilder : VehicleBuilder<BusBuilder>
{
...
}
At that point, your WithWheels
method will still return a BusBuilder
so you can still call WithRoute
.
You'll also need a new Build
method in each derived class builder, mind you...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With