我想在具有 20 多个字段的 DynamoDB 上定义一个 DAO。在 Java 中,我可以使用 Lombok 并执行类似的操作以避免一堆样板代码。
@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 中的 setter 会不同,而步骤 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>
.
这是唯一的方法吗 - 为每种类型创建一个单独的映射和方法?还是有更优雅的方式来做到这一点?
最佳答案
好吧,我认为使用 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);
// ...
}
应该这样称呼:
myDao.addField(FIELD_1_DEF, key, value);
关于java - 如何围绕 setter 创建通用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51719446/