【问题标题】:Is there a name for this pattern with closures?这种带闭包的模式有名称吗?
【发布时间】:2012-04-19 10:35:39
【问题描述】:

我经常看到在我们需要在访问对象之前执行查找代码的情况下使用一种模式。使用此模式时,通常以单词with 开头。

例如,我们需要先从数据库中检索客户记录,然后才能使用它们:

def withCustomer (id, closure) {
    def customer = getCustomer(id)
    closure(customer)
}

withCustomer(12345) { customer ->
    println "Found customer $customer.name"
}

Groovy 在闭包和匿名函数之间没有这样的区别。也许,我可以问一下这种模式是否有匿名函数的名称。

【问题讨论】:

    标签: design-patterns language-agnostic groovy closures terminology


    【解决方案1】:

    这是策略模式。闭包包含一些要作为参数传递给函数的行为,以便函数可以接受不同的行为。请参阅 Peter Norvig 的演示文稿Design Patterns in Dynamic Languages

    策略是一个变量,其值是一个函数(例如, 一流的功能,模式是不可见的)

    【讨论】:

    【解决方案2】:

    在 Groovy 的 Closures - Formal Definition 中,它被称为“Passing Closures to Methods”。

    Groovy 有一个特殊情况,将闭包定义为方法参数,以使闭包语法更易于阅读。具体来说,如果方法的最后一个参数是闭包类型,您可以使用括号外的显式闭包块调用该方法。例如,如果一个类有一个方法:

    class SomeCollection {
        public void each ( Closure c )
    }
    

    然后你可以在括号外使用闭包定义来调用each():

    SomeCollection stuff = new SomeCollection();
    stuff.each() { println it }
    

    也可以使用更传统的语法,还要注意在 Groovy 中很多情况下可以省略括号,所以这两种变体也是合法的:

    SomeCollection stuff = new SomeCollection();
    
    stuff.each { println it }       // Look ma, no parens
    stuff.each ( { println it } )   // Strictly traditional
    

    即使方法有其他参数,同样的规则也适用。唯一的限制是闭包参数必须是最后一个:

    class SomeCollection {
      public void inject ( x, Closure c )
    }
    
    stuff.inject( 0 ) { count, item -> count + item  }     // Groovy
    stuff.inject( 0, { count, item -> count + item  } )    // Traditional
    

    这可能与“Groovy 问题”无关,但例如在 Scala 中,这种“形式”是函数柯里化的特例:

    scala> def fun[A, B](a: A)(b: B) = {true}
    fun: [A, B](a: A)(b: B)Boolean
    
    scala> fun(1){2}
    res59: Boolean = true
    

    【讨论】:

    • 感谢您的回答,但您没有问我的问题。我问的是这个模式的名称,而不是闭包的使用。
    • 这不是一种模式,而是一种语法形式,在 Groovy 中这种语法形式的名称是“Passing Closures to Methods”。如果你想更接近“模式”这个词,Scala 中的一个例子是“function currying”(虽然你可以用 Scala 的函数 currying 做的比这种语法形式多得多,但它恰好是特例之一)。
    【解决方案3】:

    这取决于上下文。它可以是一种策略模式(参见 Nathan Hughes 的回答)。可以是模板方法模式。

    Arturo 的示例似乎是一个模板方法。您定义通用算法步骤(在这种情况下获取客户)和自定义(作为闭包传递)。

    【讨论】:

    【解决方案4】:

    最后,我认为这种模式叫做Loan Pattern

    贷款模式,确保一旦超出范围,资源就会被确定性地处置。

    您可以在此处查看有关此模式的一些信息:

    【讨论】:

      猜你喜欢
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 1970-01-01
      • 2011-04-23
      • 2019-10-02
      • 2014-07-15
      相关资源
      最近更新 更多