java - 如何围绕 setter 创建通用方法?

标签 java amazon-web-services dao lombok

我想在具有 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/

相关文章:

java - 从java中的多部分邮件内容字符串中解析附件

amazon-web-services - AWS API 网关错误响应生成 502 "Bad Gateway"

amazon-web-services - 扫描 DynamoDB 中的关键属性

java - AWS CodePipeline ElasticBeanstalk 部署失败

java - Spring Autowire - 需要接口(interface)和实现 DAO 类吗?

java - 如何模糊扫描仪输入文本?

java - 在Oracle SQL中编译Java源代码时Base64出现错误

java - DAO Factory 的示例,其数据源不会在不同版本之间更改

java - 使用 Spring Data 将数据传递到 MongoDB 的方法

java - 具有不同布局的多个按钮