After 20 or so years programming Java for the first time I wish I had multiple inheritance. But I don't so I'm looking for an alternative for this concrete problem.
The real application is some kind of ERP and somewhat complex so I try to translate this problem to cars. This only goes so far but it's the best I can do.
Lets start with an interface describing what a car can do:
public interface Car {
public String accelerate();
public String decelerate();
public String steerLeft();
public String steerRight();
}
Now we have a basic (but not abstract) implementation:
public class BasicCar implements Car {
protected final String name;
public BasicCar( String name ) {
this.name = name;
}
// In the real word this method is important and does lots of stuff like calculations and caching
protected String doDrive( String how ) {
return name + " is " + how + "ing";
}
@Override
public String accelerate() {
return doDrive( "accelerat" );
}
@Override
public String decelerate() {
return doDrive( "decelerat" );
}
// This method is important, too
protected String doSteer( String where ) {
return name + " is steering to the " + where;
}
@Override
public String steerLeft() {
return doSteer( "left" );
}
@Override
public String steerRight() {
return doSteer( "right" );
}
}
In the real world this itself is a facade to a DAO. Note that I need the methods @doDrive@ and @doSteer@ to be there because this is where the real work like some calculations, translations and caching is done.
And some more concrete implementations:
public class Sportscar extends BasicCar {
public Sportscar( String name ) {
super( name );
}
// I need to call the super method
@Override
public String doDrive( String how ) {
return super.doDrive( how ) + " fastly";
}
}
public class Truck extends BasicCar {
public Truck( String name ) {
super( name, new BasicMotor(), new TruckySteerer() );
}
// I need to call the super method
@Override
public String doSteer( String where ) {
return super.doSteer( where ) + " carefully";
}
}
What I can do right now is:
Car mcqueen = new Sportscar( "McQueen" );
mcqueen.steerLeft() //-> "McQueen is steering left"
mcqueen.accelerate() // -> "McQueen is accelerating fastly"
Car mack = new Truck( "Mack" );
mack.steerLeft() //-> "McQueen is steering left carefully"
mack.accelerate() // -> "McQueen is accelerating"
What I now want to do is combining these two into one which shares their functionallity:
Car red = new Firetruck( "Red" );
red.steerLeft() //-> "Red is steering left *carefully*"
red.accelerate() // -> "Red is accelerating *fastly*"
What I tried / thought about
I could copy&paste code from both into one class. But this is never a good idea. And in the real application this is pretty much code so it's an even worse idea.
I think I'm facing some major rewrite/refactoring here.
So I could make @Sportscar@ and @Truck@ a Decorator and for @Firetruck@ use both. But this won't work because @doSteer@ and @doDrive@ are called from within the decorated objects whereas a decorator only works for calles from the "outside". So I would have to put these methods in the decorator, too and this isn't a good idea either.
So I could use Java8's new fancy features and make @doSteer@ and @doDrive@ delegating to an interface like:
@FunctionalInterface
interface Driver {
public String doDrive( String where );
}
And feeding it to the constructor of @BasicCar@ but then (apart from getting pretty complex and getting some other rather nasty java problems with @final@) I don't have access to the state of @BasicCar@ in a good way anymore.
So currently I'm a little lost here. Any good ideas would be appretiated.
Aucun commentaire:
Enregistrer un commentaire