我想提出一个场景,它会很好:
- 有一个通用接口,
- 有各种通用基类实现它,
- 为通用基类提供子类,
- 以某种方式获得子类的非通用接口。
使困惑?请继续阅读并告诉我您对解决方案的看法。
假设我想要一个服务来提供基于任何类型的键和来自任何地方(数据库、文件等)的任何类型的对象。
作为一个好的开始,让我们创建一个适当的接口:
public interface ObjectProvider<K, V> {
V provide(K key);
}
通过这种方式,我将能够提供任何类型的实现。我想提供来自数据库和文件的对象。
让我们假设无论对象类型如何,都可以使用相同的数据库逻辑来提供基于 K 的 V。所以我可以为数据库访问编写一个通用基类:
public class DBObjectProvider<K, V> implements ObjectProvider<K, V> {
public V provide(K key) {
V v = null;
//some common DB logic to get V based on K
return v;
}
}
实际上,从文件中获取对象也是与对象类型无关的:
public class FileObjectProvider<K, V> implements ObjectProvider<K, V> {
public V provide(K key) {
V v = null;
//some common file reading logic to get V based on K
return v;
}
}
好的,现在我有两个通用类,我可以用它们来获得我想要的任何东西。
现在,我想使用其中一种通用实现来基于数据库中的 String 键获取 String 对象。此外,我想将它定义为使用 Spring XML 的 bean。我想没有办法在 Spring XML 中定义通用 bean(对吗?)所以我将创建一个适当的类。我需要做的就是:
public class DBStringStringProvider extends DBObjectProvider<String, String> {
}
现在我可以将这个bean注入任何:
private ObjectProvider<String, String> objectProvider;
一切都很好,现在是关键部分。我可以在很多方面使用我有用的 DB String-String 提供程序(hhmmm... 好吧不是真的)。假设我想用它制作一个 Web 服务。假设我想将 DBStringStringProvider 公开为 CXF Web 服务并对其进行测试。问题是此类 Web 服务的客户端代码如下所示:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(<INTERFACE>.class);
<INTERFACE> client = (<INTERFACE>) factory.create();
所以我需要一个 DBStringStringProvider 的非泛型接口,我没有,因为它扩展了它的泛型基类。
我可以执行以下操作:
用另一个接口扩展 ObjectProvider<String, String> 接口:
@WebService
public interface StringStringProvider extends ObjectProvider<String, String> {
@WebMethod
String provide(String key);
}
另外在通用基类已经实现的地方实现它:
public class DBStringStringProvider extends DBObjectProvider<String, String>
implements StringStringProvider {
}
在实现基类已经引入的相同接口时,我感到有点不舒服。但通过这种方式,我可以使用 WS 客户端:
factory.setServiceClass(StringStringProvider.class);
StringStringProvider client = (StringStringProvider) factory.create();
我的问题是:做我刚刚做的事情是一个好习惯吗?如果没有,还有其他方法吗?
这只是一种情况,如果为已定义为通用的东西提供非通用接口会很棒。