groovy中的运行时委派

时间:2017-09-26 10:51:22

标签: groovy

我试图为自己的项目找出一些东西,所以我做了这个例子来更好地解释它。类Thing有一个名为Type的委托overrides。 {:1}}中的方法应在以下时间调用:

  • 该方法在overrides
  • 中声明
  • 该方法在overrides中声明,但不在“this
  • 中声明

overrides中的方法应在以下情况下调用:

  • 该方法未在this
  • 中声明
  • 该方法继承自overridesObject
  • 方法丢失(missingMethod)

我考虑过使用@Delegate,但我需要在运行时更改覆盖。这是代码。

GroovyObject

注意:目前这不起作用,但我认为它很好地解释了这个想法。

在groovy中是否已经建立了类似这样的模式?

更新

有了这个,我就在那里。它无法在class Thing implements GroovyInterceptable { Type overrides = new BigThing() Object invokeMethod(String name, Object args) { MetaMethod thingMethod = metaClass.getMetaMethod('findDeclaredMethod', [this, name, args] as Object[]) .invoke(this, name, args) MetaMethod overrideMethod = findDeclaredMethod(overrides, name, args) if(overrideMethod) { overrideMethod.invoke(overrides, args) //maybe invoke missingMethod on overrides catch MissingMethodException and call thingMethod } else if(thingMethod) { thingMethod.invoke(this, args) } else { this.metaClass.invokeMissingMethod(this, name, args) } } MetaMethod findDeclaredMethod(Object obj, String name, Object args) { MetaMethod m = this.metaClass.getMetaMethod(name, args) if(m && m.declaringClass.theClass != Thing.getClass()) { m = null } return m } String method1() { return "from Thing method1() ${makeString()}" } String method2() { return "from Thing method2() ${makeString()}" } } interface Type { String makeString() } class BigThing implements Type { String makeString() { return "makeString()" } String method2() { return "from BigThing method2() ${makeString()}" } } assert 'from Thing method1() makeString()' == new Thing().method1() assert 'from BigThing method2() makeString()' == new Thing().method2() new Thing().with { assert 'from Thing method1() makeString()' == method1() assert 'from BigThing method2() makeString()' == method2() } 关闭中调用method2()

with

1 个答案:

答案 0 :(得分:1)

尝试简化GroovyObject.invokeMethod(String name, Object args)方法实现。您可以通过以下方式实现该方法来实现此目的:

  • 首先检查overrides是否包含具有该名称的方法,如果它存在则调用它
  • 检查当前对象是否具有该名称的方法并调用它
  • 以其他方式调用invokeMissingMethod

我已经检查了以下实现,并且工作正常:

class Thing implements GroovyInterceptable {
    Type overrides = new BigThing()

    Object invokeMethod(String name, Object args) {
        MetaMethod method = overrides.metaClass.getMetaMethod(name, args)
        if (method != null) {
            return method.invoke(overrides, args)
        }

        method = this.metaClass.getMetaMethod(name, args)
        if (method != null) {
            return method.invoke(this, args)
        }

        return this.metaClass.invokeMissingMethod(this, name, args)
    }

    String method1() {
        return "from Thing method1() ${makeString()}"
    }
    String method2() {
        return "from Thing method2() ${makeString()}"
    }
}

interface Type {
    String makeString()
}

class BigThing implements Type {
    String makeString() {
        return "makeString()"
    }

    String method2() {
        return "from BigThing method2() ${makeString()}"
    }
}

assert 'from Thing method1() makeString()' == new Thing().method1()
assert 'from BigThing method2() makeString()' == new Thing().method2()

我希望它有所帮助。