Is there a name for this pattern with closures?

I often see a pattern used in circumstances where we have look-up code that needs to be executed before we have access to an object. When using this pattern, usually begins with the word with .

For example, we have customer records that need to be retrieved from a database before we can use them:

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

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

Groovy makes no such distinction between closures or anonymous functions. Perhaps, I could ask if there is a name for this pattern with anonymous functions.


This is the Strategy pattern. The closure holds some piece of behavior to be passed into the function as an argument, so that the function can accept different behaviors. See Peter Norvig's presentation Design Patterns in Dynamic Languages:

The strategy is a variable whose value is a function (Eg, with first-class functions, pattern is invisible)


In Groovy's Closures - Formal Definition it is just called " Passing Closures to Methods ".

Groovy has a special case for defining closures as method arguments to make the closure syntax easier to read. Specifically, if the last argument of a method is of type Closure, you may invoke the method with an explicit closure block outside of the parenthesis. For example, if a class has a method:

class SomeCollection {
    public void each ( Closure c )
}

Then you may invoke each() with a closure definition outside of the parenthesis:

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

The more traditional syntax is also available, and also note that in Groovy you can elide parenthesis in many situations, so these two variations are also legal:

SomeCollection stuff = new SomeCollection();

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

The same rule applies even if the method has other arguments. The only restriction is that the Closure argument must be last:

class SomeCollection {
  public void inject ( x, Closure c )
}

stuff.inject( 0 ) { count, item -> count + item  }     // Groovy
stuff.inject( 0, { count, item -> count + item  } )    // Traditional

That may not be relevant to the "Groovy question", but for example in Scala, this "form" is a special case of function 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

It depends on the context. It can be a Strategy pattern (see Nathan Hughes' answer). It can be a Template Method pattern.

Arturo's example seems to be a Template Method. You define common algorithm steps (getting a customer in this case) and customizations (passed as a closure).

链接地址: http://www.djcxy.com/p/51498.html

上一篇: 什么是自由变量?

下一篇: 这种模式是否有封闭的名称?