These days I'm learning design patterns. There are a lot of documentation about programming design patterns, but I'm interesting in closure design patterns.
I found a presentation of Venkat Subramaniam about Design Patterns in Java and Groovy, and extract some patterns of this presentation that involves closures and others patterns based on my own experience.
A pair of operation that needs to be performed before and after operations.
def operations(closure) {
println "Open"
closure()
println "Close"
}
operations { println "Operation" }
===> Open
===> Operation
===> Close
Specify the behavior of an object at runtime.
def selectValues(number, closure) {
def list = []
1.upto(number) {
if (closure(it)) list << it
}
return list
}
assert [2, 4, 6, 8, 10] == selectValues(10) { it % 2 == 0 } // even
assert [1, 3, 5, 7, 9] == selectValues(10) { it % 2 != 0 } // odd
Allows sequential access to the elements.
def listNumbers(closure) {
(0..5).each { closure it }
}
listNumbers {
if (it < 3) println "$it is a little number"
else println "$it is a big number"
}
===> 0 is a little number
===> 1 is a little number
===> 2 is a little number
===> 3 is a big number
===> 4 is a big number
===> 5 is a big number
Create and execute a conditional operation.
def greet(user, successClosure, failClosure) {
if (isAdmin(user)) successClosure()
else failClosure()
}
greet(user, { println "Hi Admin!" }, { println "Hello User" })
I want to know more closure design patterns. Is there any reference about this topic? Feel free to write a new pattern in you favorite programming language.
I wrote a post about this topic (Groovy and Ruby but same content):
Closure Design Patterns
Closure Design Patterns. Ruby Edition
Closure
. Similar to Ruby's Proc
s I think. BTW, I also agree that naming some of the common uses of functions as first-class objects is not of much value; I'd stick with saying that a function that expects another function as a parameter, or that returns a function, is a "high order function" and that's all hehe. But I also think it's cool to try and find these patterns : - epidemian 2012-04-04 00:39
I think you're confusing closure with lambda/anonymous functions?
Closure is a lexical context that has bound variables. In short, if you define a function from within a function, the inner function has access to variables defined in the outer function. The "lexical context" in this case is the outer function.
Lambdas are functions that don't have a variable assignment. In Ruby, for example, you can pass blocks to functions, and the function can call it inside using only the yield
keyword. In JavaScript you can define a function and pass it as an argument at the same time. Your examples are all this.
First-class functions are yet another thing, which are functions that can be passed around like regular objects. You can pass them as arguments to function calls and hold references to them. This would be like Ruby's Proc
. In JS, all functions are first-class and all functions are objects.
In JavaScript we can illustrate all 3 with a silly example:
function foo(func) {
func();
}
var bar = function() { // bar is a first-class function
var i = 5;
foo(function() { // this is the anonymous function (lambda)
console.log(i); // i is the closure-bound variable
});
}
foo(bar); // Prints 5
So, this makes your question confusing. Closure is a language feature, not a design pattern. There are plenty of design patterns whose implementation could use closure or lambda or modulo or constructors or whatever, as you've shown yourself with those examples. Although none of those are classical design patterns, so I'm not sure I would even call them that. Maybe I'd call them sugar.
Java can implement all kinds of design patterns, but has none of these features. A lot of this kind of stuff is done with interfaces, a completely different language feature.
As people have said, these aren't really "patterns", and are reasonably specific to Groovy, but another two uses of Closures are:
def sum = { Collection a -> a.sum() }
def first2 = { Collection a -> a.take( 2 ) }
def take2andAdd = sum << first2
println take2andAdd( [ 1, 2, 3, 4 ] ) // Prints 3
def add = { a, b -> a + b }
def add2 = add.curry( 2 )
println add2( 3 ) // Prints 5
And of course, these can be combined:
def square = { a -> a * a }
def add = { a, b -> a + b }
def add2 = add.curry( 2 )
def add2andSquare = square << add2
println add2andSquare( 3 ) // prints 25
I agree with the other responses in that it doesn't really make sense to talk about closure design patterns (especially when it seems you are really talking about first-class functions ;) ). I think the point you are really trying to get at is how you can use tools such as first-class functions, lambdas and closures when implementing design patterns. Although it is specific to Groovy, you might find it useful to look at this page: http://groovy.codehaus.org/Design+Patterns+with+Groovy
For example, the "Loan my Resource Pattern" shows how to use Closures in a way very similar to your "Execute Around Method" pattern, and the "Visitor Pattern" is one that also makes good use of Closures and isn't included in your list.
selectValues
(well, any of the above examples), for instance. Anyway ... I don't really "get" this question - NoName 2012-04-03 23:52