在编写转换代码时,覆盖asType()的替代方法是什么?

Ric*_*ell 6 grails groovy

看来,在Groovy中转换对象的惯例是使用as运算符和覆盖asType().例如:

class Id {
    def value

    @Override
    public Object asType(Class type) {
        if (type == FormattedId) {
            return new FormattedId(value: value.toUpperCase())
        }
    }
}

def formattedId = new Id(value: "test") as FormattedId
Run Code Online (Sandbox Code Playgroud)

但是,Grails asType()在运行时覆盖了所有对象的实现,因此它可以支持像这样的习语render as JSON.

另一种方法是asType()在Grails Bootstrap类中重写如下:

def init = { servletContext ->
    Id.metaClass.asType = { Class type ->
        if (type == FormattedId) {
                return new FormattedId(value: value.toUpperCase())
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这会导致代码重复(DRY),因为您现在需要在Bootstrap Id类中重复上述操作,否则as FormattedId将无法在Grails容器外工作.

在Groovy/Grails中编写转换代码还有哪些替代方法可以破坏良好的代码/ OO设计原则,如Single Responsibility Principal或DRY?Mixins在这里用得好吗?

Ric*_*ell 1

您可以使用 Grails 对编解码器的支持来自动将encodeAs*函数添加到您的 Grails 原型中:

class FormattedIdCodec {

    static encode = { target ->
        new FormattedId((target as String).toUpperCase()
    }

}
Run Code Online (Sandbox Code Playgroud)

然后您可以在代码中使用以下内容:

def formattedId = new Id(value: "test").encodeAsFormattedId
Run Code Online (Sandbox Code Playgroud)