次のようなシナリオを提示したいと思います。
- 汎用インターフェースを持っている、
- さまざまな汎用基本クラスに実装してもらい、
- 汎用基本クラスのサブクラスを提供し、
- どういうわけか、サブクラスへの非ジェネリックインターフェイスを取得します。
混乱している?読んで、あなたが解決策についてどう思うか教えてください。
あらゆる種類のキーに基づいて、どこからでも(DB、ファイルなど)、あらゆる種類のオブジェクトを提供するサービスが必要だとします。
良いスタートを切るために、適切なインターフェースを作成しましょう。
public interface ObjectProvider<K, V> {
V provide(K key);
}
このようにして、あらゆる種類の実装を提供できるようになります。データベースとファイルからオブジェクトを提供したい。
Kに基づくVの提供は、オブジェクトタイプに関係なく、同じDBロジックで実行できると仮定します。したがって、DBアクセス用の汎用基本クラスを記述できます。
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;
}
}
さて、今では、必要なものを取得するために使用できる2つの汎用クラスがあります。
ここで、これらの一般的な実装の1つを使用して、データベースからStringキーに基づいてStringオブジェクトを取得したいと思います。さらに、SpringXMLを使用してBeanとして定義したいと思います。Spring XMLで汎用Beanを定義する方法はないと思います(私は正しいですか?)ので、代わりに適切なクラスを作成します。私がする必要があるのは:
public class DBStringStringProvider extends DBObjectProvider<String, String> {
}
今、私はこのBeanを任意の場所に注入できます。
private ObjectProvider<String, String> objectProvider;
すべてが順調です、今重要な部分です。便利なDBString-Stringプロバイダーをさまざまな方法で利用できました(hhmmm ... okではありません)。それからWebサービスを作りたいとしましょう。DBStringStringProviderをCXFWebサービスとして公開し、テストするとします。問題は、そのような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();
私の質問は:私が今やったことをするのは良い習慣ですか?そうでない場合、他の方法はありますか?
これは、ジェネリックとして定義されているものに対して非ジェネリックインターフェイスを使用するのが最適なシナリオの1つにすぎません。