1
我想弄清楚自己的项目,所以我让这个例子更好地解释它。类Thing
有一个代表Type
调用overrides
。当overrides
方法应该叫:groovy中的运行时代表团
- 方法在
overrides
- 方法在
overrides
宣布已宣告但尚未在`在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中是否有这样的东西已经建立模式?
更新:
有了这个我有一部分在那里。它在method2()
的with
关闭中失败。
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()
}
感谢您的帮助。当我回家时,我将不得不尝试它。我担心的一件事是GroovyObject方法。我使用'.with {}'很多。任何这些方法都应该使用'this'。我认为声明类的检查将有助于防止在'overrides'上调用这些方法。 –
@JohnMercier您能否给我们一个使用'.with {}'关闭的例子?我也想测试它:) –
我已经更新了问题,以包括一个例子和更多的信息。 –