闭包和访客模式之间是否存在显着差异?

时间:2012-04-11 17:30:26

标签: java oop design-patterns groovy closures

我最近一直在和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 }

2 个答案:

答案 0 :(得分:4)

如果您的观点是说每个函数都是访问者模式的实现,那么您是对的。您传递一个闭包,而不是传递接口的匿名实现。

封闭不是访客。在这种情况下,闭包用于实现访问者。

当然,在引擎盖下,闭包是通过内部类实现的,所以如果你的观点是说闭包不是什么神奇的话,我们大多数人都同意。

关于java中闭包和匿名类之间的区别,有一些重要的范围要点,最明显的是访问非最终变量,以及可配置的委派策略。

在groovy中,您还可以通过表示对实例方法的一种引用来实例化闭包,如下所示:

def c=this.&doSomething

这将创建一个MethodClosure,您可以使用它来传输您的方法,并将模块化的粒度从Class减少到Method。

所以我们开始离访客模式很远,不是吗?

我认为最终在我的理解中,闭包是一种使方法成为一等公民并从功能风格编程中获益的OO方法。

答案 1 :(得分:3)

缺少的关键部分是已访问对象需要accept方法。在上面描述的示例中,each构造中的项目不保证有任何方法......

each构造更类似于循环。

我还要指出闭包是一个范围构造,而访问者模式是一种设计模式。所以从这个角度来看,他们绝对没有没有彼此做。