これは半重大な提案ですが、mikera's answerをタイプセーフに変更することができます。
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);
}
:
:ちょうどlulzため
APropertyMap properties = new APropertyMap();
properties.put(AProperty.FOO, "skidoo");
properties.put(AProperty.BAR, 23);
A a = new A(properties);
、私たちも、マップに流れるようなインターフェイスを与えることができます
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
はA
のコンストラクタを呼び出すメソッドbuild
を成長させることができ、本質的にそれをビルダーに変換することができます。
また、これらのオブジェクトの一部をより一般的なものにすることもできます。 AProperty
およびAPropertyMap
は、非常に単純なA
固有のサブクラスを使用して、機能ビットを行った汎用ベースクラスを持つことができます。
特にエンタープライズを感じていて、ドメインオブジェクトがJPA2エンティティの場合は、メタモデル属性をプロパティオブジェクトとして使用できます。これにより、マップ/ビルダーはもう少し作業をしていますが、まだ簡単です。私は、45行で作業するジェネリックビルダーを持っています。エンティティごとに1つの1行のメソッドを含むサブクラスがあります。
ビルダーにゲッターが必要なく、Aのコンストラクターをプライベートにすることもできます。これにより、コンストラクタの代わりにbuild()メソッドのパラメータをチェックすることもできます。 –
真。私はAのctorを非公開にすることを検討しました。それはおそらくもっときれいです。 –
もう1つの利点は、ビルダーが、パラメータに応じて、A、ABis、またはATer(AのサブクラスであるAbisとAter)のインスタンスを返すことを選択できることです。 –