Groovy 将所有后续调用委托给另一个对象引用
我有一个方法,它需要一个特定的类作为参数Groovy 将所有后续调用委托给另一个对象引用,groovy,Groovy,我有一个方法,它需要一个特定的类作为参数 def walkOver(IWalker instance) { def list = [1, 2, 3, 4, 5] list.each { instance.enterItem(it) if (it.isOdd()) { instance.enterOdd(it) instance.exitOdd(it) } else {
def walkOver(IWalker instance) {
def list = [1, 2, 3, 4, 5]
list.each {
instance.enterItem(it)
if (it.isOdd()) {
instance.enterOdd(it)
instance.exitOdd(it)
} else {
instance.enterEven(it)
instance.exitEven(it)
}
instance.exitItem(it)
}
}
基本上,我遍历一个列表,并对其元素执行某些操作
ClassIWalker
看起来像这样
class IWalker {
void enterItem(item) { }
void exitItem(item) { }
void enterOdd(item) { }
void exitOdd(item) { }
void enterEven(item) { }
void exitEven(item) { }
void enterCommon(item) { }
void exitCommon(item) { }
}
class CompositeWalker extends IWalker {
@Lazy def oddWalker = new OddWalker()
@Lazy def evenWalker = new EvenWalker()
void enterItem(item) {
if (item.isOdd()) {
// delegate all IWalker calls to oddWalker
}
}
void exitItem(item) {
// return to current object
}
}
我有两个IWalker
的原始子类,它们只执行特定的任务
class OddWalker extends IWalker {
void enterOdd(item) {
println "Odd: $item"
}
void exitOdd(item) {}
void enterCommon(item) {}
void exitCommon(item) {}
}
class EvenWalker extends IWalker {
void enterEven(item) {
println "Even: $item"
}
void exitEven(item) {}
void enterCommon(item) {}
void exitCommon(item) {}
}
我还有一个复合walker,它应该将操作委托给相应的IWalker
实现的实例
class CompositeWalker extends IWalker {
@Lazy def oddWalker = new OddWalker()
@Lazy def evenWalker = new EvenWalker()
def currentRef = this // default
void enterItem(item) {}
void exitItem(item) {}
void enterOdd(item) {
currentRef = oddWalker
currentRef.enterOdd(item)
}
void exitOdd(item) {
currentRef.exitOdd(item)
currentRef = this
}
void enterEven(item) {
currentRef = evenWalker
currentRef.enterEven(item)
}
void exitEven(item) {
currentRef.exitEven(item)
currentRef = this
}
void enterCommon(item) {
if (currentRef == this) {
// code
} else {
currentRef.enterCommon(item)
}
}
void exitCommon(item) {
if (currentRef == this) {
// code
} else {
currentRef.enterCommon(item)
}
}
}
我希望我的CompositeWalker
将walkOver
方法中所有方法的后续调用委托给相应的对象
目前,我存储了对当前对象的引用,并仅调用其方法
理想情况下,我想做这样的事情
class IWalker {
void enterItem(item) { }
void exitItem(item) { }
void enterOdd(item) { }
void exitOdd(item) { }
void enterEven(item) { }
void exitEven(item) { }
void enterCommon(item) { }
void exitCommon(item) { }
}
class CompositeWalker extends IWalker {
@Lazy def oddWalker = new OddWalker()
@Lazy def evenWalker = new EvenWalker()
void enterItem(item) {
if (item.isOdd()) {
// delegate all IWalker calls to oddWalker
}
}
void exitItem(item) {
// return to current object
}
}
在那里,我根本没有在compositeWalker
内部实现oddwarker
和evenWalker
方法
可以这样做吗?通过使用@Delegate注释,您可以摆脱常见方法的实现
class CompositeWalker extends IWalker {
@Lazy IWalker oddWalker = new OddWalker()
@Lazy IWalker evenWalker = new EvenWalker()
@Delegate
IWalker currentRef = this // default
void enterItem(item) {}
void exitItem(item) {}
void enterOdd(item) {
currentRef = oddWalker
currentRef.enterOdd(item)
}
void exitOdd(item) {
currentRef.exitEven(item)
currentRef = this
}
void enterEven(item) {
currentRef = evenWalker
currentRef.enterEven(item)
}
void exitEven(item) {
currentRef.exitEven(item)
currentRef = this
}
}
对我来说,你的代码有些问题。请注意,您正在调用
isOdd()
两次:在walkOver()
中和在CompositeWalker
中。所以你基本上做了两次相同的决定。另外,IWalker
中的偶数/奇数对及其相应的偶数/奇数实现是一条线索,表明您使用策略模式的方式可能存在缺陷
虽然让复合程序员
委托给合适的IWalker
,但我认为有更好的方法;根据我对你代码的理解。我提出了一种重构方法,使用工厂来选择合适的walker,让walker做自己的事情,而完全不考虑项目是偶数还是奇数;因为已经做出了选择。下面是:
def walkOver(IWalkerFactory factory) {
def list = [1, 2, 3, 4, 5]
list.each {
def walker = factory.get(it)
walker.enterItem(it)
walker.exitItem(it)
}
}
interface IWalker {
void enterItem(item)
void exitItem(item)
void enterCommon(item)
void exitCommon(item)
}
interface IWalkerFactory<T> {
IWalker get(T obj)
}
abstract class AbstractWalker implements IWalker {
void enterItem(item) { }
void exitItem(item) { }
void enterCommon(item) { }
void exitCommon(item) { }
}
class OddWalker extends AbstractWalker {
void enterItem(item) {
println "Odd: $item"
}
}
class EvenWalker extends AbstractWalker {
void enterItem(item) {
println "Even: $item"
}
}
class WalkerFactory implements IWalkerFactory<Number> {
@Lazy IWalker oddWalker = new OddWalker()
@Lazy IWalker evenWalker = new EvenWalker()
IWalker get(Number number) {
if(number.isOdd()) oddWalker
else evenWalker
}
}
def巡检(IWalkerFactory工厂){
def列表=[1,2,3,4,5]
列出每个{
def walker=工厂。获取(it)
walker.enterItem(it)
walker.exitItem(it)
}
}
接口IWalker{
无效项目(项目)
无效出口(项目)
无效(项目)
作废exitCommon(项目)
}
接口IWalkerFactory{
IWalker get(T obj)
}
抽象类AbstractWalker实现了IWalker{
无效输入项(项){}
无效出口(项目){}
无效(项目){}
无效exitCommon(项目){}
}
类OddWalker扩展了AbstractWalker{
无效项目(项目){
println“奇数:$item”
}
}
类EvenWalker扩展了AbstractWalker{
无效项目(项目){
println“偶数:$item”
}
}
类WalkerFactory实现IWalkerFactory{
@Lazy IWalker oddWalker=新oddWalker()
@Lazy IWalker evenWalker=新evenWalker()
IWalker获取(编号){
if(number.isOdd())oddWalker
艾尔斯伊文沃克
}
}
简而言之,walkeOver()
要求IWalkerFactory
返回适合该项目的IWalker
。IWalkerFactory
实现是唯一关心偶数/奇数的代码。然后,walkOver()
只调用由IWalkerFactory
返回的IWalker
上的方法
这种方法的一个好处是,它不再需要一个
复合程序
,它是策略和状态机的融合。如果您可以避免使用状态机,未来的开发人员将感谢您。因此,当调用common
方法时,它将引用currentRef
中的当前引用?是的,它将调用委托上的任何方法,该方法在this
中未被覆盖,实际上我无权访问walkOver
方法(我模仿了另一个图书馆的行为)所以我不能改变它。是的,我也发现这个结构有点奇怪,但怀疑这不是故意的。