オキシ:
私は20+のフィールドを持つDynamoDBの上でDAOを定義したいです。Javaでは、私は、定型コードの束を避けるために、ロンボクを使用して、このような何かを行うことができます。
@Setter
@Getter
@DynamoDBTable("MyTable")
public class MyDAO {
//FIELD_1, FIELD_2, FIELD_3 defined as static final String elsewhere
@DynamoDBAttribute(attribute = FIELD_1)
private final String field1;
@DynamoDBAttribute(attribute = FIELD_2)
private final Long field2;
@DynamoDBAttribute(attribute = FIELD_3)
private final int field3;
...
}
問題は、私は次のような各フィールドのために何かをした方法を持っていた場合はステップ2でセッターは異なるだろうし、ステップ3でフィールド名が異なることになるので、私は、何度も何度も、コードを複製終わるだろう(すなわちsetField1
第一およびsetField2
)秒間。
public void addField1(String key, String field1Value) {
//Wrap some retry logic and error handling around the following
// 1. get DAO for key
// 2. set FIELD_1 to field1Value in DAO if not set
// 3. put DAO in DynamoDB using attribute name FIELD_1
}
public void addField2(String key, Long field2Value) {
//Wrap some retry logic and error handling around the following
// 1. get DAO for key
// 2. set FIELD_2 to field2Value in DAO if not set
// 3. put DAO in DynamoDB using attribute name FIELD_2
}
理想的には、私のような何かがしたいaddField
、私はすべてのフィールドのためにすべてを複製する必要はありませんので、すべての再試行ロジックで、以下の方法を。
private void addField(String fieldName, String key, Object value);
public void addField1(String key, String field1Value) {
addField(FIELD_1, key, (Object) field1Value);
}
私は、次のようなフィールド名とBiConsumers間のマップを試してみました
Map<String, BiConsumer<MyDAO, Object>> setterMap =
new HashMap<String, BiConsumer<MyDAO, Object>>(){{
put(FIELD_1, MyDAO::setField1);
put(FIELD_2, MyDAO::setField2);
}};
private void addField(String fieldName, String key, Object value) {
...
// 2. Use setterMap.get(fieldName).accept(value);
...
}
問題は、私は、私はキャストすることはできませんというエラーを取得されBiConsumer<MyDAO, String>
にをBiConsumer<MyDAO, Object>
。
種類ごとに別々のマップやメソッドを作成する - それはそれを行うための唯一の方法ですか?それともこれを行うにはよりエレガントな方法は何ですか?
トマシュLinkowski:
まあ、私はそれが使用して行うことは可能だとは思わないMap
場合、あなたは型の安全性を維持したいです。代わりに、ここで私はどうなるのかです:
1)私はそのような特別なクラスを作成したいです:
@AllArgsConstructor
@Getter
final class FieldDefinition<T> {
private final String name;
private final BiConsumer<MyDAO, T> setter;
}
2)次に、私がで定数を作成したいMyDAO
、でも良く、近くにいくつかのヘルパーオブジェクト内(またはMyDAO
)そのような:
static final FieldDefinition<String> FIELD_1_DEF = new FieldDefinition<>(FIELD_1, MyDAO::setField1);
3)最後に、私は次のタイプセーフ作成したいaddField
方法を:
private <T> void addField(FieldDefinition<T> fieldDefinition, String key, T value) {
// ...
fieldDefinition.getSetter().accept(this, value);
// ...
}
これは、そのように呼ばれることwhould:
myDao.addField(FIELD_1_DEF, key, value);