为 java 不可变对象实现 Groovy 构建器的最佳方法
The best way to implement Groovy builder for java immutable object
我有一个不可变的 Java 对象,如下所示:
public class Entity {
private String field1;
private String field2;
public Entity(String field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
public String getField1() {...}
public String getField2() {...}
}
我想在我的测试代码中为 Groovy 中编写的 class 添加一个构建器。为此,我尝试使用 @groovy.transform.builder.Builder
。
在这里,我无法更改实体 class 作为产品代码中的实体,因此我尝试将构建器与 groovy.transform.builder.ExternalStrategy
策略一起使用。
@Builder(builderStrategy = ExternalStrategy, forClass = Entity)
class EntityBuilder {
}
但我不能将它用于不可变对象。
所以我想知道为不可变 java 对象实施 groovy 构建器的最佳方法是什么?
不是真正的构建器,但您可以将 List 强制转换为您的类型,只要它具有可以将 List 项作为参数的构造函数即可:
def entity = [ 'hi', 'hej' ] as Entity
如果你的类型有一个接受 2 个字符串的构造函数,这就有效。
由于您的类型没有 setter,Groovy 无法猜测哪个参数具有哪个名称,因此无法自动生成构建器。
但是,您可以手动编写一些代码以获得一些不错的代码。
例如:
@Builder
class GroovyEntity {
String field1
String field2
def asType( Class type ) {
if ( type == Entity ) {
return new Entity( field1, field2 )
}
super.asType( type )
}
}
你可以这样使用:
Entity entity = GroovyEntity.builder()
.field1( 'hi' )
.field2( 'hej' )
.build() as Entity
快速回答是没有 Groovy 构建器转换可以为您的情况创建构建器。所以你必须手动编码。不能使用构建器转换的原因有两个:
- 字段不是 public,因此转换看不到它们,因此不会为它们创建生成器方法。
- 生成的
build()
方法期望构建的 class 包含每个字段的无参数构造函数和设置器。
为了说明我的意思,下面是为满足要求的 class 生成的构建器代码片段:
@groovy.transform.builder.Builder(forClass = Person, builderStrategy = groovy.transform.builder.ExternalStrategy)
public class PersonBuilder implements groovy.lang.GroovyObject extends java.lang.Object {
private java.lang.String firstName
private java.lang.String lastName
...
public PersonBuilder firstName(java.lang.String firstName) {
this .firstName = firstName
return this
}
public PersonBuilder lastName(java.lang.String lastName) {
this .lastName = lastName
return this
}
public Person build() {
Person _thePerson = new Person()
_thePerson .firstName = firstName
_thePerson .lastName = lastName
return _thePerson
}
...
}
我有一个不可变的 Java 对象,如下所示:
public class Entity {
private String field1;
private String field2;
public Entity(String field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
public String getField1() {...}
public String getField2() {...}
}
我想在我的测试代码中为 Groovy 中编写的 class 添加一个构建器。为此,我尝试使用 @groovy.transform.builder.Builder
。
在这里,我无法更改实体 class 作为产品代码中的实体,因此我尝试将构建器与 groovy.transform.builder.ExternalStrategy
策略一起使用。
@Builder(builderStrategy = ExternalStrategy, forClass = Entity)
class EntityBuilder {
}
但我不能将它用于不可变对象。
所以我想知道为不可变 java 对象实施 groovy 构建器的最佳方法是什么?
不是真正的构建器,但您可以将 List 强制转换为您的类型,只要它具有可以将 List 项作为参数的构造函数即可:
def entity = [ 'hi', 'hej' ] as Entity
如果你的类型有一个接受 2 个字符串的构造函数,这就有效。
由于您的类型没有 setter,Groovy 无法猜测哪个参数具有哪个名称,因此无法自动生成构建器。
但是,您可以手动编写一些代码以获得一些不错的代码。
例如:
@Builder
class GroovyEntity {
String field1
String field2
def asType( Class type ) {
if ( type == Entity ) {
return new Entity( field1, field2 )
}
super.asType( type )
}
}
你可以这样使用:
Entity entity = GroovyEntity.builder()
.field1( 'hi' )
.field2( 'hej' )
.build() as Entity
快速回答是没有 Groovy 构建器转换可以为您的情况创建构建器。所以你必须手动编码。不能使用构建器转换的原因有两个:
- 字段不是 public,因此转换看不到它们,因此不会为它们创建生成器方法。
- 生成的
build()
方法期望构建的 class 包含每个字段的无参数构造函数和设置器。
为了说明我的意思,下面是为满足要求的 class 生成的构建器代码片段:
@groovy.transform.builder.Builder(forClass = Person, builderStrategy = groovy.transform.builder.ExternalStrategy)
public class PersonBuilder implements groovy.lang.GroovyObject extends java.lang.Object {
private java.lang.String firstName
private java.lang.String lastName
...
public PersonBuilder firstName(java.lang.String firstName) {
this .firstName = firstName
return this
}
public PersonBuilder lastName(java.lang.String lastName) {
this .lastName = lastName
return this
}
public Person build() {
Person _thePerson = new Person()
_thePerson .firstName = firstName
_thePerson .lastName = lastName
return _thePerson
}
...
}