这个模式的名称是否有闭包?

时间:2012-04-05 16:58:02

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

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

例如,在我们可以使用之前,我们需要从数据库中检索客户记录:

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

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

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

4 个答案:

答案 0 :(得分:4)

这是策略模式。闭包持有一些行为作为参数传递给函数,因此函数可以接受不同的行为。见Peter Norvig的演讲Design Patterns in Dynamic Languages

  

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

答案 1 :(得分:2)

在Groovy的Closures - Formal Definition中,它被称为“将闭包传递给方法”。

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

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

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

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中,这种“形式”是函数currying 的特例:

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

答案 2 :(得分:1)

这取决于具体情况。它可以是一种策略模式(参见Nathan Hughes的回答)。它可以是模板方法模式。

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

答案 3 :(得分:1)

最后,我认为这种模式称为贷款模式

贷款模式,确保资源在超出范围时确定性地处置。

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

相关问题