這只是一個半認真的建議,但我們可以修改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;
}
}
而且:先進的設計模式和/或模糊的Java的技巧就知道這是
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));
}
}
愛好者一個類型安全的異構容器。只是很感謝,我也沒有使用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行的通用構建器,每個實體的子類包含一個單行方法。
你甚至不需要在構建器中使用getter,而A的構造函數可以是私有的。這也允許檢查build()方法中的參數而不是構造函數。 – 2012-07-07 22:09:17
是的。我考慮讓A的ctor私密。這可能更乾淨。 – 2012-07-07 22:11:51
另一個優點是,構建器可以根據參數選擇返回A,ABis或ATer(Abis和Ater是A的子類)的實例。 – 2012-07-07 22:14:47