【发布时间】:2017-11-15 17:31:32
【问题描述】:
我目前在一家拥有多种模块的公司工作。在该公司中,如果您想提供模块内部,您可以通过 java 接口提供它,该接口隐藏实际的实现类型并为请求模块提供接口。现在我希望有一个提供者能够为多个模块提供数据,这些模块公开实际内部数据的不同字段或方法。
因此,我有一个内部对象,其中包含一些数据,并且每个模块都有一个接口,需要访问一些但不是严格来说所有字段。最后,我有一个外部对象,它实现了所有这些接口,并拥有一个内部对象的实例来委托方法调用:
public class InternalObject {
public int getA() { return 0; }
public int getB() { return 0; }
}
public interface ModuleXObject {
int getA();
}
public interface ModuleYObject {
int getA();
int getB();
}
public class ExternalObject implements ModuleXObject, ModuleYObject {
private InternalObject _internal;
public int getA() { return _internal.getA(); }
public int getB() { return _internal.getB(); }
}
现在这一切都很好,但如果我想提供 - 让我们说 - 用于查找为正确模块键入的所述对象列表的存储库方法,我会遇到如何实现这一点的问题。我希望得到以下内容:
public interface ModuleXObjectRepository {
List<ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List<ExternalObject> loadAllObjects() {
// ...
}
}
这不会编译,说返回类型不兼容。 所以我的问题是,是否有可能实现这样的目标,如果,如何实现?
我应该指出,我尝试了一些不同的方法,我想将它们包括在内以保持完整性并描绘它们的缺点(在我看来)。
方法一:
public interface ModuleXObjectRepository {
List<? extends ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<? extends ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List<ExternalObject> loadAllObjects() {
// ...
}
}
这种方法非常接近我想要的解决方案,但会产生如下代码:
List<? extends ModuleXObject> objects = repository.loadAllObjects();
因此要求用户在每个 List-Declaration 中包含关于 loadAllObjects() 调用的“? extends”。
方法2:
public interface ModuleXObjectRepository {
List<ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List loadAllObjects() {
// ...
}
}
这种方法只是省略了 ExternalObjectRepository 中的泛型,因此在我看来过多地降低了类型安全性。另外我还没有测试这是否真的有效。
只是为了重新练习,是否有任何可能的方法来定义 loadAllObjects 方法,使用户能够在没有
的情况下获取使用其各自模块的对象键入的列表- 在用户代码中需要“?extends”
- 降低存储库实现中的类型安全性
- 使用类/接口级别的泛型
【问题讨论】:
-
嗨,泰勒,感谢您的评论!事实上,我已经考虑过以某种方式使用“超级”,但我想不出哪个是确切的解决方案。至少
<T super ModuleXObject & ModuleYObject> List<T> loadAllObjects()不起作用。你有更好的主意吗? -
我将添加我的详细答案。给我几个