これはやや深刻な提案にすぎませんが、ミケラの答えをタイプセーフに変更することができます。
私たちが持っていると言う:
public class A {
private final String foo;
private final int bar;
private final Date baz;
}
次に、次のように記述します。
public abstract class AProperty<T> {
public static final AProperty<String> FOO = new AProperty<String>(String.class) {};
public static final AProperty<Integer> BAR = new AProperty<Integer>(Integer.class) {};
public static final AProperty<Date> BAZ = new AProperty<Date>(Date.class) {};
public final Class<T> propertyClass;
private AProperty(Class<T> propertyClass) {
this.propertyClass = propertyClass;
}
}
と:
public class APropertyMap {
private final Map<AProperty<?>, Object> properties = new HashMap<AProperty<?>, Object>();
public <T> void put(AProperty<T> property, T value) {
properties.put(property, value);
}
public <T> T get(AProperty<T> property) {
return property.propertyClass.cast(properties.get(property));
}
}
高度なデザインパターンやあいまいなJavaトリックの愛好家は、これをタイプセーフな異種コンテナとして認識します。私も使用しなかったことに感謝しgetGenericSuperclass()
ます。
次に、ターゲットクラスに戻ります。
public A(APropertyMap properties) {
foo = properties.get(AProperty.FOO);
bar = properties.get(AProperty.BAR);
baz = properties.get(AProperty.BAZ);
}
これはすべて次のように使用されます。
APropertyMap properties = new APropertyMap();
properties.put(AProperty.FOO, "skidoo");
properties.put(AProperty.BAR, 23);
A a = new A(properties);
lulzの場合は、マップに流暢なインターフェイスを与えることもできます。
public <T> APropertyMap with(AProperty<T> property, T value) {
put(property, value);
return this;
}
これにより、発信者は次のように書くことができます。
A a = new A(new APropertyMap()
.with(AProperty.FOO, "skidoo")
.with(AProperty.BAR, 23));
これに対して行うことができる小さな改善がたくさんあります。のタイプは、AProperty
よりエレガントに処理できます。APropertyMap
コンストラクターの代わりに静的ファクトリを使用して、そのようなことに興味がある場合は、より流暢なスタイルのコードを使用できます。のコンストラクターを呼び出すメソッドを拡張して、本質的にビルダーに変えることAPropertyMap
ができます。build
A
これらのオブジェクトのいくつかをかなり一般的にすることもできます。AProperty
そして、非常に単純な特定のサブクラスAPropertyMap
を使用して、機能ビットを実行する汎用基本クラスを持つことができます。A
特にエンタープライズを感じていて、ドメインオブジェクトがJPA2エンティティである場合は、メタモデル属性をプロパティオブジェクトとして使用できます。これにより、マップ/ビルダーはもう少し作業を行うことになりますが、それでもかなり単純です。私は45行で動作する汎用ビルダーを持っており、エンティティごとに1行のメソッドを含むサブクラスがあります。