具有强制参数的 Lombok 构建器
Lombok's builder with mandatory parameters
如果我将@Builder 添加到 class。生成器方法已创建。
Person.builder().name("john").surname("Smith").build();
我有一个要求,其中某个特定字段是必填项。在这种情况下,名称字段是强制性的。理想情况下,我想这样声明。
Person.builder("john").surname("Smith").build();
在谷歌搜索时,我发现了很多替代方法,例如覆盖构建器实现,如下所示:
@Builder
public class Person {
private String name;
private String surname;
public static PersonBuilder builder(String name) {
return new PersonBuilder().name(name);
}
}
然后像下面这样使用它:
Person p = Person.builder("Name").surname("Surname").build();
上述方法的问题是它仍然提供如下的 name() 和 PersonBuilder() 方法,我不想要这样的方法:
Person p = Person.builder("Name").surname("Surname").name("").build();
Person p = new Person.PersonBuilder().build;
另一种方法是在名称上添加@lombok.nonnull 检查,这将在创建对象时强制为名称提供值。但这是一个运行时检查。它不会强迫我在创建对象时为名称提供值。
lombok 是否提供了任何额外的技术来实现以下目标:
Person p = Person.builder("Name").surname("Surname").build();
注意:不应公开 builder() 和 name()。创建 Person 对象的唯一方法应该是在上面或下面:
Person p = Person.builder("Name").build();
你不能用 lombok 真正做到这一点,请参阅 the explanation from the library authors。但是自己动手做这个builder有那么复杂吗?
public static class PersonBuilder {
private final String name;
private String surname;
PersonBuilder(String name) {
this.name = name;
}
public PersonBuilder surname(String surname) {
this.surname = surname;
return this;
}
public Person build() {
return new Person(name, surname);
}
}
使用您已有的相同方法:
public static PersonBuilder builder(String name) {
return new PersonBuilder(name);
}
尝试将生成器设为私有。
你看这条评论了吗
我很确定你再读一遍这个帖子就会知道了。
P.S。如果你有一个只有两个字段的 class 最好直接使用构造函数。
最佳实践:
import lombok.Builder;
import lombok.NonNull;
@Builder(builderMethodName = "privateBuilder")
public class Person {
@NonNull
private String name;
private String surname;
public static class PersonNameBuilder {
public PersonBuilder name(String name) {
return Person.privateBuilder().name(name);
}
}
private static class PersonExtraBuilder extends PersonBuilder{
@Deprecated
@Override
public PersonBuilder name(String name) {
return this;
}
}
public static PersonNameBuilder builder(String name) {
return new PersonNameBuilder();
}
private static PersonExtraBuilder privateBuilder(){
return new PersonExtraBuilder();
}
}
用法:
PersonNameBuilder nameBuilder = Person.builder();
PersonBuilder builder = nameBuilder.name("John");
Person p1 = builder.surname("Smith").build();
// Or
Person p2 = Person.builder().name("John").surname("Smith").build();
// The last `.name("")` will not work, and it will be marked as Deprecated by IDE.
Person p3 = Person.builder().name("John").surname("Smith").name("").build();
如果我将@Builder 添加到 class。生成器方法已创建。
Person.builder().name("john").surname("Smith").build();
我有一个要求,其中某个特定字段是必填项。在这种情况下,名称字段是强制性的。理想情况下,我想这样声明。
Person.builder("john").surname("Smith").build();
在谷歌搜索时,我发现了很多替代方法,例如覆盖构建器实现,如下所示:
@Builder
public class Person {
private String name;
private String surname;
public static PersonBuilder builder(String name) {
return new PersonBuilder().name(name);
}
}
然后像下面这样使用它:
Person p = Person.builder("Name").surname("Surname").build();
上述方法的问题是它仍然提供如下的 name() 和 PersonBuilder() 方法,我不想要这样的方法:
Person p = Person.builder("Name").surname("Surname").name("").build();
Person p = new Person.PersonBuilder().build;
另一种方法是在名称上添加@lombok.nonnull 检查,这将在创建对象时强制为名称提供值。但这是一个运行时检查。它不会强迫我在创建对象时为名称提供值。
lombok 是否提供了任何额外的技术来实现以下目标:
Person p = Person.builder("Name").surname("Surname").build();
注意:不应公开 builder() 和 name()。创建 Person 对象的唯一方法应该是在上面或下面:
Person p = Person.builder("Name").build();
你不能用 lombok 真正做到这一点,请参阅 the explanation from the library authors。但是自己动手做这个builder有那么复杂吗?
public static class PersonBuilder {
private final String name;
private String surname;
PersonBuilder(String name) {
this.name = name;
}
public PersonBuilder surname(String surname) {
this.surname = surname;
return this;
}
public Person build() {
return new Person(name, surname);
}
}
使用您已有的相同方法:
public static PersonBuilder builder(String name) {
return new PersonBuilder(name);
}
尝试将生成器设为私有。
你看这条评论了吗
我很确定你再读一遍这个帖子就会知道了。
P.S。如果你有一个只有两个字段的 class 最好直接使用构造函数。
最佳实践:
import lombok.Builder;
import lombok.NonNull;
@Builder(builderMethodName = "privateBuilder")
public class Person {
@NonNull
private String name;
private String surname;
public static class PersonNameBuilder {
public PersonBuilder name(String name) {
return Person.privateBuilder().name(name);
}
}
private static class PersonExtraBuilder extends PersonBuilder{
@Deprecated
@Override
public PersonBuilder name(String name) {
return this;
}
}
public static PersonNameBuilder builder(String name) {
return new PersonNameBuilder();
}
private static PersonExtraBuilder privateBuilder(){
return new PersonExtraBuilder();
}
}
用法:
PersonNameBuilder nameBuilder = Person.builder();
PersonBuilder builder = nameBuilder.name("John");
Person p1 = builder.surname("Smith").build();
// Or
Person p2 = Person.builder().name("John").surname("Smith").build();
// The last `.name("")` will not work, and it will be marked as Deprecated by IDE.
Person p3 = Person.builder().name("John").surname("Smith").name("").build();