5

A menudo veo un patrón utilizado en circunstancias donde tenemos código de búsqueda que debe ejecutarse antes de tener acceso a un objeto. Al usar este patrón, generalmente comienza con la palabra with.¿Hay un nombre para este patrón con cierres?

Por ejemplo, tenemos los registros de clientes que necesitan ser recuperados de una base de datos antes de poder utilizarlos:

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

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

maravilloso no hace tal distinción entre cierres o funciones anónimas. Quizás, podría preguntar si hay un nombre para este patrón con funciones anónimas.

Respuesta

4

Este es el patrón de estrategia. El cierre contiene algún tipo de comportamiento para pasar a la función como argumento, de modo que la función puede aceptar diferentes comportamientos. Ver presentación de Peter Norvig Design Patterns in Dynamic Languages:

La estrategia es una variable cuyo valor es una función (por ejemplo, con funciones de primera clase, el patrón es invisible)

+0

¿Qué opinas sobre [@mgryszko answer] (http://stackoverflow.com/a/10093625/462015) –

+0

@Arturo: pensé que el método de la plantilla implica necesariamente herencia, donde la estrategia era una alternativa a ella, no una forma de ello. http://tech.puredanger.com/2007/07/03/pattern-hate-template/ –

+0

¿Qué opina de [mi propia respuesta] (http://stackoverflow.com/a/10306434/462015)? –

2

En Groovy Closures - Formal Definition se acaba de llamar "Pasando los cierres a los métodos".

Groovy tiene un caso especial para definir cierres como argumentos de método para facilitar la lectura de la sintaxis de cierre. Específicamente, si el último argumento de un método es de tipo Cierre, puede invocar el método con un bloque de cierre explícito fuera del paréntesis. Por ejemplo, si una clase tiene un método:

class SomeCollection { 
    public void each (Closure c) 
} 

entonces puede invocar cada uno() con una definición de cierre fuera del paréntesis:

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

La sintaxis más tradicional también está disponible, y también Cabe destacar que en Groovy se puede eludir paréntesis en muchas situaciones, por lo que estas dos variaciones también son legales:

SomeCollection stuff = new SomeCollection(); 

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

la misma regla se aplica incluso si el método tiene otros argumentos. La única restricción es que el argumento de cierre debe ser el último:

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

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

que pueden no ser relevantes para la "cuestión maravilloso", pero por ejemplo en Scala, esta "forma" es un caso especial de función 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 
+0

Gracias por la respuesta, pero no hacer mi pregunta. Pregunté el nombre de este patrón, no el uso de cierres. –

+0

esto no es un patrón, sino una forma de sintaxis, y el nombre para esta forma de sintaxis en Groovy es "** Pasar los cierres a métodos **". Si desea estar más cerca de la palabra "patrón", un ejemplo en Scala es "** función de currying **" (aunque hay mucho más que puede hacer con la función de currar de Scala que esta forma de sintaxis, pero simplemente sucede que ser uno de los casos especiales). – tolitius

1

Depende del contexto. Puede ser un patrón de Estrategia (ver la respuesta de Nathan Hughes). Puede ser un patrón de Método de plantilla.

El ejemplo de Arturo parece ser un Método de plantilla. Define pasos de algoritmo comunes (obtener un cliente en este caso) y personalizaciones (pasadas como cierre).

+0

¿Qué opinas sobre [mi propia respuesta] (http://stackoverflow.com/a/10306434/462015)? –

1

Finalmente, creo que este patrón se llama Loan Pattern.

El patrón de préstamo asegura que un recurso se elimine determinísticamente una vez que se sale del alcance.

se puede ver algo de información acerca de este patrón aquí:

Cuestiones relacionadas