Java泛型 - 太复杂了?如何简化?

Lpp*_*Edd 10 java generics design-patterns

最初我在CodeReview上发布了这个问题,但这更适合StackOverflow.

我正在编写一个使用Java 6的多步骤过程.假设有3个步骤.
每个都接受相同类型的输入.让我们开始.

这是作为输入传递给每个步骤的对象.此对象充当另一类对象的包装器,以及一些步骤的共享值.请注意,名称会被翻译为更通用的域名,而英文版本的原始文件则是意大利语.

public class EntityStepInput<T extends Entity> {
    public final T entity;
    public boolean modified;
    public boolean canceled;

    public EntityStepInput(final T entity) {
        this.entity = entity;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是每个步骤使用的接口.

public interface EntityStep<T extends EntityStepInput<? extends Entity>> {
    void process(final T stepInput) throws Exception;
}
Run Code Online (Sandbox Code Playgroud)

现在,3个步骤中的2个必须接受EntityStepInput包含Entity从中派生的任何类型的a .

public class FirstEntityStep implements EntityStep<EntityStepInput<? extends Entity>> {
    @Override
    public void process(final EntityStepInput<? extends Entity> stepInput) throws Exception {}
}

public class SecondEntityStep implements EntityStep<EntityStepInput<? extends Entity>> {
    @Override
    public void process(final EntityStepInput<? extends Entity> stepInput) throws Exception {}
}
Run Code Online (Sandbox Code Playgroud)

最后一步必须接受EntityStepInput包含从中派生的特定类型的Entity.

public class ThirdEntityStep implements EntityStep<EntityStepInput<? extends DerivedEntity>> {
    @Override
    public void process(final EntityStepInput<? extends DerivedEntity> stepInput) throws Exception {}
}
Run Code Online (Sandbox Code Playgroud)

用法很简单.我有重载方法,接受不同类型的Entitys.以下是简化版本.

public void workWithEntity(final DerivedEntity entity) throws Exception {
    final EntityStepInput<DerivedEntity> stepInput = new EntityStepInput<DerivedEntity>(entity);

    stepOne.process(stepInput);
    stepTwo.process(stepInput);
    stepThree.process(stepInput);
}
Run Code Online (Sandbox Code Playgroud)

如您所见,该DerivedEntity类型可以使用所有步骤.

public void workWithEntity(final OtherDerivedEntity entity) throws Exception {
    final EntityStepInput<OtherDerivedEntity> stepInput = new EntityStepInput<OtherDerivedEntity>(entity);

    stepOne.process(stepInput);
    stepTwo.process(stepInput);
}
Run Code Online (Sandbox Code Playgroud)

而这里的另一种类型Entity不能使用最后一步,这就是我想要的.

现在,这与泛型变得相当复杂.我担心在我离开之后谁会阅读我的代码将不会理解,迟早会发生混乱.

这可以简化吗?您的方法将尽可能多地尊重单一责任原则?

编辑.Entity层次结构如下:

Entity > DerivedEntity
Entity > OtherDerivedEntity
Run Code Online (Sandbox Code Playgroud)

Rad*_*def 2

一个较小的更改只是将类型变量声明简化为EntityStepanEntity而不是 an EntityStepInput

interface EntityStep<E extends Entity> {
    void process(EntityStepInput<? extends E> i);
}
Run Code Online (Sandbox Code Playgroud)

进而:

class FirstEntityStep implements EntityStep<Entity> {
    @Override
    public void process(EntityStepInput<? extends Entity> i) {}
}
class SecondEntityStep implements EntityStep<Entity> {
    @Override
    public void process(EntityStepInput<? extends Entity> i) {}
}
class ThirdEntityStep implements EntityStep<DerivedEntity> {
    @Override
    public void process(EntityStepInput<? extends DerivedEntity> i) {}
}
Run Code Online (Sandbox Code Playgroud)

和以前一模一样,但是声明更容易理解一些。

T extends EntityStepInput<...>仅当您想使用某些特定的子类时才需要,但由于您总是EntityStepInput直接使用,因此不需要它。