Search code examples
design-patternslanguage-agnosticgroovyclosures

Closure Design Patterns


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.

Execute Around Method

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

Pluggable Behavior

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

Iterator Pattern

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

Dynamical Conditional Execution

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.


Update

I wrote a post about this topic (Groovy and Ruby but same content):
Closure Design Patterns
Closure Design Patterns. Ruby Edition


Solution

  • 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.