最初我在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;
}
}
这是每个步骤使用的接口(interface)。
public interface EntityStep<T extends EntityStepInput<? extends Entity>> {
void process(final T stepInput) throws Exception;
}
现在,这3个步骤中的2个必须接受一个
EntityStepInput
,其中包含一个Entity
或从其派生的任何类型。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 {}
}
最后一步必须接受
EntityStepInput
,其中包含从Entity
派生的特定类型。public class ThirdEntityStep implements EntityStep<EntityStepInput<? extends DerivedEntity>> {
@Override
public void process(final EntityStepInput<? extends DerivedEntity> stepInput) throws Exception {}
}
用法很简单。我有重载的方法,它们接受不同类型的
Entity
。接下来是一个简化的版本。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);
}
如您所见,
DerivedEntity
类型能够使用所有步骤。public void workWithEntity(final OtherDerivedEntity entity) throws Exception {
final EntityStepInput<OtherDerivedEntity> stepInput = new EntityStepInput<OtherDerivedEntity>(entity);
stepOne.process(stepInput);
stepTwo.process(stepInput);
}
在这里,另一种
Entity
无法使用最后一步,这就是我想要的。现在,使用泛型变得相当复杂。我担心谁会在我走后阅读我的代码,这将不明白,迟早会造成困惑。
这是可简化的吗?在遵循单一责任原则的前提下,您想采取什么方式来尊重他人?
编辑。
Entity
层次结构如下:Entity > DerivedEntity
Entity > OtherDerivedEntity
最佳答案
较小的更改只是将EntityStep
上的类型变量声明简化为Entity
而不是EntityStepInput
:
interface EntityStep<E extends Entity> {
void process(EntityStepInput<? extends E> i);
}
然后:
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) {}
}
它与以前完全相同,但是声明更容易理解。
如果要使用某些特定的子类,则只需要
T extends EntityStepInput<...>
,但是由于您始终直接使用EntityStepInput
,因此不需要它。