如何对多个耦合对象使用泛型?

How to use generics with multiple coupled objects?

所以我无法围绕正确的设计来解决这个问题。

我的应用程序有两个控制状态的关键对象,它们需要相互交互:ItemList、ItemState。它们都依赖于一个通用的 ITEM_TYPE,因此它们可以在不同的上下文中发挥作用。它们也是抽象的,以允许 ITEM_TYPE 依赖行为。

这两部分都需要知道通用类型,而且,由于它们相互通信,因此它们需要知道彼此的通用类型。 (一个 ItemList< String > 实例需要知道它的 ItemState 字段是一个 ItemState< String > ,反之亦然)。

我目前的解决方案有效,但看起来很糟糕。一定有更好的方法。这就是我现在正在做的事情:

public abstract class ItemState<
  ITEM_TYPE,
  STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
  LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {

}
public abstract class ItemList<
  ITEM_TYPE,
  STATE_TYPE extends ItemState<ITEM_TYPE, STATE_TYPE, LIST_TYPE>,
  LIST_TYPE extends ItemList<ITEM_TYPE, STATE_TYPE, LIST_TYPE>> {

}

然后一个实施 class 可能看起来像:

class StringState extends ItemState<String, StringState, StringList> {

}
class StringList extends ItemList<String, StringState, StringList> {

}

请注意,对于 ItemState,STATE_TYPE 是对实现 class 的引用,对于 ItemList/LIST_TYPE.

也是如此

如果我只是让 ItemState 成为 ItemList 的内部 class,我的问题真的会得到解决,因为会有一个隐式绑定并且它们可以共享通用声明,但是两个 classes 都太大了和独立的,我不想这样做。

有什么建议吗?

编辑:作为评论的反例:

public abstract class ItemState<ITEM_TYPE> {  
  public abstract ItemList getItemList();  
  public void doSomething() {
    // This should not compile because abstract super class has
    // no idea what the generic type of getItemList() is
    ITEM_TYPE item = this.getItemList.getItem(); 
  }  
}

编辑 2:我认为我能想到的最佳解决方案就是让 ItemList/ItemState 以一种或另一种方式继承,这样它们就可以像 class 一样发挥作用。我不喜欢这个解决方案,因为它覆盖了关注点分离,但它使泛型更易于管理。

旁注:我的实际应用程序有 4 个交织在一起的问题 classes,为了简单起见,我只使用了 2 个。实际上,泛型非常糟糕,难以理解且难以重构(每个 class 大约有 4 整行泛型声明)。我现在已经把这4个class变成了垂直继承层次

JM Yang 的解决方案很好

我认为您在声明这 2 个 类 时可能只是引用泛型类型 ITEM_TYPE。

我能够正确编译以下代码。

public abstract class ItemList<ITEM_TYPE> {
    public abstract ItemState<ITEM_TYPE> getState();

    public abstract ITEM_TYPE getItem();
}

public abstract class ItemState<ITEM_TYPE> {
    public abstract ItemList<ITEM_TYPE> getItemList();

    public void doSomething() {
        ITEM_TYPE item = getItemList().getItem();
        System.out.println(item);
    }
}

public class StringList extends ItemList<String> {
    @Override
    public StringState getState() {
        return new StringState();
    }

    @Override
    public String getItem() {
        return "";
    }
}

public class StringState extends ItemState<String> {
    @Override
    public StringList getItemList() {
        return new StringList();
    }
}