多重继承的替代方案

Sch*_*tod 29 java inheritance design-patterns

经过20多年的Java编程,我希望自己有多重继承.但我并非如此,我正在为这个具体问题寻找替代方案.

真正的应用程序是某种ERP,有点复杂,所以我试图将这个问题转化为汽车.这只是到目前为止,但这是我能做的最好的.

让我们从描述汽车可以做什么的界面开始:

public interface Car {

    public String accelerate();
    public String decelerate();

    public String steerLeft();
    public String steerRight();
}
Run Code Online (Sandbox Code Playgroud)

现在我们有一个基本的(但不是抽象的)实现:

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" );
    }
}
Run Code Online (Sandbox Code Playgroud)

在现实世界中,这本身就是DAO的外观.请注意,我需要这些方法doDrive,doSteer因为这是完成一些计算,翻译和缓存等实际工作的地方.

还有一些更具体的实现:

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

我现在能做的是:

Car mcqueen = new Sportscar( "McQueen" );
mcqueen.steerLeft() //-> "McQueen is steering left"
mcqueen.accelerate() // -> "McQueen is accelerating fastly"

Car mack = new Truck( "Mack" );
mack.steerLeft() //-> "Mack is steering left carefully"
mack.accelerate() // -> "Mack is accelerating"
Run Code Online (Sandbox Code Playgroud)

我现在要做的是将这两者合二为一,共享其功能:

Car red = new Firetruck( "Red" );
red.steerLeft() //-> "Red is steering left *carefully*"
red.accelerate() // -> "Red is accelerating *fastly*"
Run Code Online (Sandbox Code Playgroud)

我试过/想过的

我可以将两者的代码复制并粘贴到一个类中.但这绝不是一个好主意.在实际的应用程序中,这几乎是代码,所以这是一个更糟糕的想法.

我想我在这里面临一些重大的重写/重构.

所以我可以Sportscar和Truck一个装饰师一起Firetruck使用.但这不起作用,因为doSteer并且doDrive从装饰对象内部调用,而装饰器仅适用于来自"外部"的calles.所以我也必须将这些方法放在装饰器中,这也不是一个好主意.

所以我可以使用Java8的新功能,并制作doSteer和doDrive委托给以下界面:

@FunctionalInterface
interface Driver {
    public String doDrive( String where );
}
Run Code Online (Sandbox Code Playgroud)

然后将它提供给构造函数BasicCar 然后(除了变得相当复杂并得到一些其他相当讨厌的java问题final)我再也无法BasicCar以一种好的方式访问状态了.

所以目前我在这里有点失落.任何好的想法都会被认可.

编辑:举例说明这在现实世界中的表现:该doSteer组可能是这样的:

class ProductImpl {
    String getTitle(){
        return getField( "title" );
    }
    String getTeaser(){
        return getField( "teaser" );
    }
    String getField( String name ){
        Locale loc = configuredLocale();
        Map vars = configuredVarialbes();
        String value = getCached( name, loc );
        value = translateVariables( value );
        value = replaceVariables( value, vars );
        // and more
    }
}
Run Code Online (Sandbox Code Playgroud)

Gab*_*iel 10

您可以使用模式策略来定义不同的行为,并使子类实现它们.

就像在这张图片中: 模式策略

它是法语(下面的字典),但非常明显:

  • 所有继承的类Personnage都是视频游戏中使用的字符.
  • 所有实现接口的类(EspritCombatif,Deplacement,Soin)定义的界面的方法.他们是行为.
  • 的Personnage类包含每个右边定义的接口的对象.
  • 每个字符(子类Personnage)通过combat = new CombatCouteau();在构造函数中执行例如a来选择要实现的代码.

因此,如果你只想改变所有与刀战斗的人的行为,你只需更改代码即可CombatCouteau.


字典:

  • Personnage =性格
  • Guerrier =战士
  • Medecin =医生
  • Chirurgien =外科医生
  • Couteau = Knife
  • 手枪=枪
  • Marcher =走路
  • Courir = Run
  • Premier soin =急救
  • Opération=手术
  • Esprit combatif =好斗的心灵
  • 战斗,战斗=战斗,战斗
  • 代替,移动,移动,移动
  • soin,soigner =愈合,愈合