2

我最近一直在玩 Groovy,之前也玩过 JRuby,很欣赏.each{}在他们的集合中使用闭包。

也就是说,我不禁觉得这不过是访问者模式的语法糖。如果您将代码封装在一个类中的闭包主体中,并使用访问者模式传递该类的一个实例,这似乎是完全相同的事情,尽管麻烦较少。

那么,是否还有其他我还没有看到的闭包功能使它们与访问者模式有根本的不同,或者人们真的对这种语法糖感到兴奋吗?

对我来说,这似乎更像是一个图书馆问题而不是语言问题。


这是一个 Java 列表的快速模型,它的行为似乎类似于eachGroovy 列表中的闭包。

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 }
4

2 回答 2

4

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

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

当然,在幕后,闭包是通过内部类实现的,所以如果你的意思是说闭包没有什么神奇之处,我们大多数人都会同意。

关于 java 中闭包和匿名类之间的区别,有一些重要的范围界定点,最值得注意的是对非最终变量的访问和可配置的委托策略。

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

def c=this.&doSomething

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

所以我们开始远离访问者模式了,不是吗?

我认为最后在我的理解中,闭包是一种使方法成为一等公民并获得函数式编程的好处的 OO 方式。

于 2012-04-11T18:25:00.123 回答
3

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

each结构更类似于循环。

我还要指出,闭包是一种作用域构造,而访问者模式是一种设计模式。所以从这个角度来看,他们绝对没有任何关系。

于 2012-04-11T17:33:54.017 回答