Java泛型-太复杂了吗?如何简化? [英] Java generics - too complicated? How to simplify?

查看:134
本文介绍了Java泛型-太复杂了吗?如何简化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最初我在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

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 Entitys. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆