Mailgun serviceを使用してメールを送信するのはlittle libraryです。Java genericsを使用してコンバータSPIを設計する適切な方法
ライブラリは、現在、ある種のHTML DSLを使用してリッチメールの本文コンテンツを生成する非常に簡単なメカニズムを備えています。私はあなたが望むようにフォーマットされたオブジェクトを渡すことができるように、コンバータのSPIを提供したいところの次のバージョンで作業しています。数字、日付、通貨価値などについて考えています。
ジェネリックス、ワイルドカードの種類、境界などに苦しんでいます。私の問題はジェネリックスの使用法の詳細よりも一般的な設計だと思います。だから私の質問は、どのように私は私のSPIを設計する必要がありますJavaジェネリックの制限を与えます。私は、コンバータインタフェースを定義開始している
は:
public interface ContentConverter<T> {
String toString(T value);
}
ライブラリ全体で使用される構成オブジェクトがあります。そこで、ユーザは、この登録メソッドを使用して、そのインタフェースのインスタンスを登録することになっています。
public <T> Configuration registerConverter(ContentConverter<? super T> converter,
Class<T> classToConvert)
{
converters.add(new Converter<>(classToConvert, converter));
return this;
}
Converter
クラスは、コンバータとそれのクラスをencapsuleするための内部クラスです。
private final static class Converter<T> {
private Class<T> classOfConverter;
private ContentConverter<? super T> contentConverter;
Converter(Class<T> classOfConverter,
ContentConverter<? super T> contentConverter)
{
this.classOfConverter = classOfConverter;
this.contentConverter = contentConverter;
}
}
Configuration
はコンバータのリストを保持します。
private List<Converter<?>> converters = ...
最後に、この設定ではオンデマンド変換が提供されます。
@SuppressWarnings("unchecked")
public <T> ContentConverter<T> converter(Class<T> classToConvert) {
for (Converter<?> converter : converters)
if (classToConvert.isAssignableFrom(converter.classOfConverter))
return (ContentConverter<T>) converter.contentConverter;
return (ContentConverter<T>) defaultConverter;
}
デフォルトコンバータは、単にObject.toString()
を呼び出しています。
private final static ContentConverter<Object> defaultConverter =
new ContentConverter<Object>() {
@Override
public String toString(Object value) {
return value.toString();
}
};
ユーザーが本文メッセージを作成しているとき、これらの2つの方法のいずれかを呼び出して、構成済みコンバータを使用してオブジェクトを追加できます。
public Builder text(Object value) {
ContentConverter<?> converter = configuration.converter(value.getClass());
return text(value, converter);
}
public <T> Builder text(T value, ContentConverter<T> converter) {
return text(converter.toString(value));
}
public Builder text(String s) {
[...] // this is where the content is really appendend
return this;
}
しかし、これは機能しません。最初のメソッドはコンパイルされません。私はさまざまな組み合わせを試しましたが、問題はより深く、タイプの消去については何かと思います。
値のキャストも必要であるためコンパイルされません – Jorge
@Jorge値がT – wero
です。パラメータタイプも変更されていません。 – Jorge