6

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

ただし、Grails はasType()実行時に for all オブジェクトの実装を上書きして、 のようなイディオムをサポートできるようにしrender as JSONます。

asType()別の方法として、Grails Bootstrap クラスを次のように書き直すこともできます。

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

ただし、これはコードの重複 (DRY) につながります。BootstrapId クラスの両方で上記を繰り返す必要があるためです。そうしas FormattedIdないと、Grails コンテナーの外部では機能しません。

単一責任プリンシパルや DRY などの優れたコード/OO 設計プリンシパルを壊さない、Groovy/Grails での変換コードの記述に代わるものはありますか? ミックスインはここで役に立ちますか?

4

2 に答える 2

1

コーデックのGrailsサポートを使用しencodeAs*て、Grailsアーキタイプに関数を自動的に追加できます。

class FormattedIdCodec {

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

}

次に、コードで次を使用できます。

def formattedId = new Id(value: "test").encodeAsFormattedId
于 2013-01-10T17:43:27.173 に答える
0

私の洗練されていない解決策は、元の asType() の名前を変更し、それを呼び出す新しい asType() を作成し、そのメソッドの呼び出しで BootStrap に asType を上書きさせることです。

だから、あなたのクラス:

class Id {
    def value

    @Override
    public Object asType(Class type) {
        return oldAsType(type);
    }

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

私のアプリでは、いくつかのクラスで asType を定義していたので、BootStrap.groovy で一般的なクロージャーを使用することになりました。

    def useOldAsType = {Class clazz ->
        delegate.oldAsType(clazz)
    }

    Id.metaClass.asType = useOldAsType;
    Value.metaClass.asType = useOldAsType;
    OtherClass.metaClass.asType = useOldAsType;
    SubclassOfValue.metaClass.asType = useOldAsType;

asType をオーバーライドしないサブクラスがあり、そのサブクラスでスーパークラスを使用する場合は、BootStrap にも設定する必要があることに注意してください。

于 2013-05-01T19:57:26.087 に答える