如何使用Groovy';s@Builder是否也要复制POGO?

如何使用Groovy';s@Builder是否也要复制POGO?,groovy,copy-constructor,builder,Groovy,Copy Constructor,Builder,Groovy的@Builder注释实质上是将Builder模式添加到一个类中,通常是一个POGO。我想做的是类似于下面的事情,我认为它类似于一个复制构造函数 给定类Foo,Foo的现有实例,我想执行以下操作: Foo copy = Foo.builder(foo).methodOne(...).methodTwo(...)...build() 也就是说,能够将实例foo传递给builder(),但这不是(当前)API的一部分。我认为,如果有一种方法可以将POGO转换为Map,那么就有一种方法可

Groovy的
@Builder
注释实质上是将Builder模式添加到一个类中,通常是一个POGO。我想做的是类似于下面的事情,我认为它类似于一个复制构造函数

给定类
Foo
Foo
的现有实例,我想执行以下操作:

Foo copy = Foo.builder(foo).methodOne(...).methodTwo(...)...build()
也就是说,能够将实例
foo
传递给
builder()
,但这不是(当前)API的一部分。我认为,如果有一种方法可以将POGO转换为
Map
,那么就有一种方法可以构建POGO——但显然没有那么干净

有了这样的解决方案,用户还可以通过从现有数据构建新类来绕过
@Immutable
类,而无需手动映射每个属性

有人知道我该如何做到这一点吗


更新:我后来了解到@Immutable使所有字段都是私有的,因此不能将
@Immutable
@Builder
一起使用,因此,如果想要拥有遵循Builder模式的不可变类,那么解决这个问题的方法会变得非常棘手。

您正在寻找一个专用的构建器吗

import groovy.transform.builder.*
import groovy.transform.*

 @ToString
 @Builder
 class Foo {
     String first, last
     int born

     Foo(){}

     @Builder(builderClassName='CopyBuilder', builderMethodName='copyBuilder')
     static Foo copy(Foo foo) {
         new Foo(first: foo.first, last: foo.last, born: foo.born)
     }
 }

def p = Foo.builder().first('Johnny').last('Depp').born(1963).build()
def c = Foo.copyBuilder().foo(p).build()
assert c != p
assert p.toString() == 'Foo(Johnny, Depp, 1963)'
assert c.toString() == 'Foo(Johnny, Depp, 1963)'

是的,这正是我想要的,但它必须是通用的。也就是说,我不想为每个模型类指定要复制的所有属性,因为
@Builder
注释的整个要点是将构建器模式添加到注释的类中。似乎修改相应的
@Builder
AST类来重载
Builder()
方法以获取同一类的实例并复制属性是相当简单的。可能是有类别或元类的东西?我还是新手,所以不确定这样做是否正确。我不明白:/你为什么不使用
clone
方法呢?此外,当涉及到对象类型(希望它适用于多个类)或不指定所有属性时,您需要它是通用的?
clone()
仅适用于实现
Cloneable
接口的对象,这意味着每个模型对象都必须实现该接口。这违背了使用Groovy的全部目的,即用更少的代码做更多的事情。但事实证明,这是一种转移注意力的做法,因为
@Builder
要求所有字段都是公共的(这样Groovy就可以生成setter方法)。这不是一个很好的解决方案,因为这意味着现在所有的数据模型在应用程序中都缺乏完整性。