我目前在一家拥有多种模块的公司工作。在该公司中,如果您想提供模块内部结构,您可以通过 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();
因此,要求用户将“? extends”包含到与调用 loadAllObjects() 有关的每个列表声明中。
方法2:
public interface ModuleXObjectRepository {
List<ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List loadAllObjects() {
// ...
}
}
在我看来,这种方法只是省略了ExternalObjectRepository 中的泛型,因此大大降低了类型安全性。另外我还没有测试这是否真的有效。
只是为了排练,是否有任何可能的方法来定义加载所有对象方法,使用户能够获取使用各自模块的对象键入的列表,而无需
- 在用户代码中需要“? extends”
- 降低存储库实现中的类型安全性
- 使用类/接口级别泛型