首页 > 解决方案 > 是否可以从静态方法开始使用 Lombok @Builder?

问题描述

我希望 Lombok 处理我的构建器 API,同时也有一个构造器开始。

我从与@Data结合的类上的构造函数开始@Builder(toBuilder = true),但这让我不得不在最终字段上强制使用无效或虚拟值以及表达力较差的流畅 API。我终于使用静态方法解决了我的情况,但我希望 Lombok 对我的用例有更好的解决方案。

使用toBuilder 的API

fooHandler.accept(new TweakedFoo(Foo.class, Mode.QUICK).toBuilder()
          .mappingOutcomeFor(FooOutcome.class)
          .mappingOutcome(toEvent(BarOutcome.class))
          .build()));

使用静态方法的 API

fooHandler.accept(tweakFoo(Foo.class, Mode.QUICK)
          .mappingOutcomeFor(FooOutcome.class)
          .mappingOutcome(toEvent(BarOutcome.class))
          .build()));

看看第二个设置如何更好地流动?

各自的龙目岛设置(简化)

@Data
@Builder(toBuilder = true)
public class TweakedFoo {

    private final Class<Foo> from;
    private final Mode mode;
    private final Class<?> to;

    public TweakedFoo(Class<Foo> from, Mode mode) {
        this.from = from;
        this.mode = mode;
        this.to = null; // eww
    }
}

和:

@Data
@Builder(builderMethodName = "useTweakedFooDotTweakedFooInsteadPlease")
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class TweakedFoo {

    private final Class<Foo> from;
    private final Mode mode;
    private final Class<?> to;

    public static TweakedFooBuilder tweakFoo(Class<Foo> from, Mode mode) {
        return TweakedFoo.useTweakedFooDotTweakedFooInsteadPlease()
                         .from(from)
                         .mode(mode);
    }

}

实际参数在这里没有多大意义,但这个设置说明了我的真实用例。

第二种方法不仅更简洁,它不需要虚拟构造函数字段初始化,而且它隐藏了构造函数,因此您无法通过构建器获取实例。但是,第二种方法需要我隐藏 Lombok 生成的构建器启动方法,以支持我自己的静态方法。

龙目岛有更好的方法吗?

标签: javalombok

解决方案


您可以builder()通过简单地自己实现来自定义您的方法:

@Data
@Builder
public class TweakedFoo {
    // ...
    public static TweakedFooBuilder builder(Class<Foo> from, Mode mode) {
        return new TweakedFooBuilder()
            .from(from)
            .mode(mode);
    }
    // ...
}

在这种情况下, Lombok 不会生成另一个builder()方法,因为它会识别具有相同名称的现有方法。如果您希望方法以不同的方式命名,例如tweakFoo,使用@Builder(builderMethodName="tweakFoo").


推荐阅读