【发布时间】:2017-09-26 10:51:21
【问题描述】:
我正在尝试为我自己的项目找出一些东西,所以我做了这个例子来更好地解释它。 Thing 类有一个名为 overrides 的委托 Type。 overrides 中的方法应在以下情况下调用:
- 方法在
overrides中声明 - 该方法在
overrides中声明,但不在`this 中
this 中的方法应在以下情况下调用:
- 该方法未在
overrides中声明 - 方法继承自
Object,GroovyObject - 方法丢失(missingMethod)
我考虑过使用@Delegate,但我需要在运行时更改覆盖。这是代码。
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()
}
注意:这目前不起作用,但我认为它很好地解释了这个想法。
在 groovy 中是否已经建立了这样的模式?
更新:
有了这个,我就成功了。在 with 闭包中调用 method2() 失败。
class Thing implements GroovyInterceptable {
Type overrides = new BigThing()
Object invokeMethod(String name, Object args) {
MetaMethod method = overrides.metaClass.getMetaMethod(name, args)
if(method != null) {
System.out.println("$method.name class is $method.declaringClass.theClass")
System.out.println("$method.declaringClass.theClass interfaces contains Type or is type ${method.declaringClass.theClass == Type || method.declaringClass.theClass.interfaces.contains(Type)}")
}
if (method != null && (method.declaringClass.theClass == Type || method.declaringClass.theClass.interfaces.contains(Type))) {
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()
new Thing().with {
assert 'from Thing method1() makeString()' == method1()
assert 'from BigThing method2() makeString()' == method2()
}
【问题讨论】:
标签: groovy