Java泛型-太复杂了吗?如何简化? [英] Java generics - too complicated? How to simplify?
问题描述
最初我在CodeReview上发布了这个问题,但这可能更适合StackOverflow。
Originally I had posted the question on CodeReview, but this is more suited for StackOverflow probably.
我正在使用Java 6为多步骤过程进行编码请说其中有3个步骤。
每个步骤都接受相同类型的输入。
让我们开始吧。
I'm coding for a multi-step process, using Java 6. Say there are 3 of these steps.
Each accepts the same type of input.
Lets begin.
这是作为输入传递给每个步骤的对象。除了某些步骤的共享值之外,该对象还用作另一种对象的包装。
请注意,名称已翻译为更通用的域,并且英语的原始名称为意大利语。
This is the object which is passed as input to each step. This object acts as a wrapper for another type of object, alongside some steps' shared values. Be aware names are translated to a more generic domain and in english, originals are in Italian.
public class EntityStepInput<T extends Entity> {
public final T entity;
public boolean modified;
public boolean canceled;
public EntityStepInput(final T entity) {
this.entity = entity;
}
}
这是每个步骤使用的界面。
This is the interface used by each step.
public interface EntityStep<T extends EntityStepInput<? extends Entity>> {
void process(final T stepInput) throws Exception;
}
现在,三个步骤中的两个必须接受 EntityStepInput
其中包含 Entity
或从其衍生的任何类型。
Now, 2 out of the 3 steps must accept an EntityStepInput
which contains a Entity
or any type derived from it.
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 $ c派生的特定类型$ c>。
The last step must accept an EntityStepInput
which contains a specific type derived from Entity
.
public class ThirdEntityStep implements EntityStep<EntityStepInput<? extends DerivedEntity>> {
@Override
public void process(final EntityStepInput<? extends DerivedEntity> stepInput) throws Exception {}
}
用法非常简单。我有重载的方法,它们接受不同类型的 Entity
s。以下是简化版本。
The usage is pretty straighforward. I have overloaded methods which accept different types of Entity
s. What follows is a simplified version.
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
类型可以使用所有步骤。
As you can see the DerivedEntity
type is able to use all of the steps.
public void workWithEntity(final OtherDerivedEntity entity) throws Exception {
final EntityStepInput<OtherDerivedEntity> stepInput = new EntityStepInput<OtherDerivedEntity>(entity);
stepOne.process(stepInput);
stepTwo.process(stepInput);
}
这是另一种 Entity
无法使用我想要的最后一步。
And here another type of Entity
cannot use the last step, which is what I want.
现在,对于泛型而言,这已经变得相当复杂。我担心走了之后谁会读我的代码,迟早会弄得一团糟。
Now, this has became quite complex with generics. I fear who will read my code after I'm gone won't understand and sooner or later a mess is going to be made.
这可简化吗?在遵循单一责任原则的前提下,您希望采取什么方式来尊重自己?
Is this simplifiable? What would your approach be like to respect as much as possibile the single responsibility principle?
编辑。 实体
层次结构如下:
Edit. Entity
hierarchy is as follow:
Entity > DerivedEntity
Entity > OtherDerivedEntity
推荐答案
一个较小的更改只是为了简化类型变量在 EntityStep
上声明为 Entity
而不是 EntityStepInput
:
One smaller change is just to simplify the type variable declaration on EntityStep
to an Entity
instead of an 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) {}
}
与以前完全相同,但声明更容易理解。
It's exactly the same as before, but the declarations are a bit easier to understand.
您只需要<$ c $如果想使用某些特定的子类,则c> T扩展EntityStepInput< ...> ,但是由于您始终直接使用 EntityStepInput
,因此您不必不需要。
You'd only need T extends EntityStepInput<...>
if you wanted to use some specific subclass, but since you always use EntityStepInput
directly, you don't need it.
这篇关于Java泛型-太复杂了吗?如何简化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!