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)
一个较小的更改只是将类型变量声明简化为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直接使用,因此不需要它。