Java BuilderTestPattern - 如何避免样板文件?

标签 java builder boilerplate bytecode-manipulation lombok

我的项目中有很多值对象。

我正在使用项目 lombok 来消除一些样板文件,因此我的值对象如下所示:

@Value
@Accessors(fluent = true)
public class ValueObject {

    private final String firstProp;
    private final int secondProp;   

}

不错,几乎没有样板文件。

现在,我在测试中经常使用全参数构造函数。它看起来很乱,所以我想我会介绍 Builder Pattern 变体:

public class ValueObjectBuilder {

    private static final int DEFAULT_VALUE_FOR_SECOND_PROP = 666;

    private String firstProp = "default value for first prop;
    private int secondProp = DEFAULT_VALUE_FOR_SECOND_PROP;

    private ValueObjectBuilder() {}

    public static ValueObjectBuilder newValueObject() {
        return new ValueObjectBuilder();
    }

    public ValueObjectBuilder withFirstProp(String firstProp) {
        this.firstProp = firstProp
        return this;
    }

    public ValueObjectBuilder withFirstProp(int secondProp) {
        this.secondProp = secondProp;
        return this;
    }

    public ValueObject build() {
        return new ValueObject(
                firstProp, secondProp
        );
    }
}

代码现在看起来相当不错:

ValueObjectBuilder
.newValueObject()
.withFirstProp("prop")
.withSecondProp(15)
.build();

现在,问题是 - 正如我提到的,我必须编写很多类似的类......我已经厌倦了复制粘贴它们。

我正在寻找的是一个黑魔法智能工具,它会以某种方式为我生成这段代码。

我知道,Lombok中有一个@Builder注解,但是不符合我的要求。原因如下:

1) 我无法在 lombok 的生成器中提供默认值。好吧,实际上,这是可能的 - 通过自己实现构建器类模板

@Builder
public class Foo {
    private String prop;

    public static class FooBuilder() {
        private String prop = "def value";
        ...
    }

}

它也会生成一些样板文件。

2) 我找不到任何方法在 lombok 的构建器中为每个字段访问器添加前缀。也许@Wither 可以在这里提供帮助?但我不知道如何正确使用它。

3) 最重要的原因:我不是在创建“自然”生成器。据我所知,lombok 旨在为给定的带注释类创建 Builder - 我不知道是否有办法从 build() 方法中返回任何其他对象。

因此,总结一下: 你知道有什么工具可以帮助我吗?或者也许我提到的所有这些事情实际上都可以使用 Lombok 实现?

编辑

好的,所以我可能找到了针对这个特殊情况的解决方案。使用 lombok 我们可以使用:

@Setter
@Accessors(chain = true, fluent = true)
@NoArgsConstructor(staticName = "newValueObject")
public class ValueObjectBuilder {
    private String firstProp = "default";
    private int secondProp = 666;

    public ValueObject build() {
        return new ValueObject(firstProp, secondProp);
    }
}

干杯, 斯拉威克

最佳答案

我知道这是旧的,但如果其他人遇到这个问题,我找到了一个为构建器提供默认值的替代解决方案。

重写构建器方法并在返回构建器之前提供默认值。所以在上面的例子中:

@Builder
public class Foo {
    private String prop;

    public static FooBuilder builder() {
        return new FooBuilder().prop("def value");
    }
}

这不是一个理想的解决方案,但胜过必须重写整个构建器本身或拥有自定义构造函数(恕我直言,如果有很多变量,这会很痛苦。如果有一些类似于 @With 的东西,那还是不错的或@Default 注释来处理这个问题。

关于Java BuilderTestPattern - 如何避免样板文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27867717/

相关文章:

java - 具有组合键的 JPA OneToMany 和 ManyToOne 正在生成第三个表

laravel - 如何获得模型的空构建器?

java - jOOQ:重用/复制查询

c# - 单次事件订阅

java - AWS S3上传图像在部署到EBS时不起作用,但在本地主机SpringBoot(JAVA)中起作用

java - 列出 ConcurrentModificationException

css - HTML5 样板中的粘性页脚

struct - Julia:如何在结构共享属性时避免样板代码

java - SmsMessage getOriginatingAddress国家代码从哪里来

java - Lombok @Singular 在构造函数上使用 @Builder 的子类中没有效果