我最近一直在和Groovy玩游戏并且之前已经搞过JRuby并且很欣赏在他们的收藏中使用.each{}
闭包。
那就是说,我不禁觉得这只不过是游客模式的语法糖。如果你将代码封装在一个类中的闭包体内,并使用访问者模式传递该类的实例,它看起来就像是完全相同的东西,虽然没那么麻烦。
那么,我是否还有其他封闭功能可以使它们与访客模式根本不同,或者人们是否真的对这种语法糖感到兴奋?
对我而言,这似乎更像是一个图书馆问题,而不是语言问题。
这是一个快速模拟Java列表,看起来像Groovy列表中的each
闭包。
public class ClosureList<E> extends ArrayList<E>{
interface Visitor<E>{
void visit( E e );
}
void accept( Visitor<E> v ){
for( Iterator<E> myItr = this.iterator(); myItr.hasNext() )
v.visit( myItr.next() );
}
}
然后只有
public class ClosureTest{
public static void main( String[] args ){
ClosureList<String> myList = new ClosureList<String>();
myList.add( "green eggs" );
myList.add( "green ham" );
clStr.accept(
new Visitor<String>(){
void visit( String s ){
System.out.println( s )
}
}
);
}
}
在Groovy中看起来是一样的:
def l = [ "green eggs", "green ham" ]
l.each{ println it }
答案 0 :(得分:4)
如果您的观点是说每个函数都是访问者模式的实现,那么您是对的。您传递一个闭包,而不是传递接口的匿名实现。
封闭不是访客。在这种情况下,闭包用于实现访问者。
当然,在引擎盖下,闭包是通过内部类实现的,所以如果你的观点是说闭包不是什么神奇的话,我们大多数人都同意。
关于java中闭包和匿名类之间的区别,有一些重要的范围要点,最明显的是访问非最终变量,以及可配置的委派策略。
在groovy中,您还可以通过表示对实例方法的一种引用来实例化闭包,如下所示:
def c=this.&doSomething
这将创建一个MethodClosure,您可以使用它来传输您的方法,并将模块化的粒度从Class减少到Method。
所以我们开始离访客模式很远,不是吗?
我认为最终在我的理解中,闭包是一种使方法成为一等公民并从功能风格编程中获益的OO方法。
答案 1 :(得分:3)
缺少的关键部分是已访问对象需要accept
方法。在上面描述的示例中,each
构造中的项目不保证有任何方法......
each
构造更类似于循环。
我还要指出闭包是一个范围构造,而访问者模式是一种设计模式。所以从这个角度来看,他们绝对没有没有彼此做。