Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the alternatives to overriding asType() when writing conversion code?

Tags:

grails

groovy

It appears the convention for converting objects in Groovy is to use the as operator and override asType(). For example:

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

However, Grails over-writes the implementation of asType() for all objects at runtime so that it can support idioms like render as JSON.

An alternative is to re-write the asType() in the Grails Bootstrap class as follows:

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

However, this leads to code duplication (DRY) as you now need to repeat the above in both the Bootstrap and the Id class otherwise the as FormattedId will not work outside the Grails container.

What alternatives exist to writing conversion code in Groovy/Grails that do not break good code/OO design principals like the Single Responsibility Principal or DRY? Are Mixins are good use here?

like image 525
Ricardo Gladwell Avatar asked Jan 09 '13 17:01

Ricardo Gladwell


1 Answers

You can use the Grails support for Codecs to automatically add encodeAs* functions to your Grails archetypes:

class FormattedIdCodec {

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

}

Then you can use the following in your code:

def formattedId = new Id(value: "test").encodeAsFormattedId
like image 182
Ricardo Gladwell Avatar answered Oct 26 '22 03:10

Ricardo Gladwell