5

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

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

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

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

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

4

4 回答 4

4

这就是策略模式。闭包包含一些要作为参数传递给函数的行为,以便函数可以接受不同的行为。请参阅 Peter Norvig 的演示动态语言中的设计模式

策略是一个变量,其值为一个函数(例如,对于一等函数,模式是不可见的)

于 2012-04-05T17:47:19.957 回答
2

在 Groovy 的闭包 - 正式定义中,它只是称为“将闭包传递给方法”。

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
于 2012-04-05T17:08:17.903 回答
1

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

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

于 2012-04-10T17:35:32.267 回答
1

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

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

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

于 2012-04-24T21:43:07.417 回答