Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 648
Arturo Herrero Avatar asked Apr 03 '12 23:04

Arturo Herrero


People also ask

What is closure design?

The principle of closure describes our tendency to perceive segmented visual elements as complete or whole objects, even when we're missing information. This principle is frequently associated with logo design, but it can influence other visual-design decisions related to icons and various page elements.

What are the 3 design patterns?

Design Patterns are categorized mainly into three categories: Creational Design Pattern, Structural Design Pattern, and Behavioral Design Pattern.

What is JS design patterns?

Design patterns are reusable solutions to commonly occurring problems in software design. They are proven solutions, easily reusable and expressive. They lower the size of your codebase, prevent future refactoring, and make your code easier to understand by other developers.


3 Answers

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.

like image 86
Tony R Avatar answered Oct 16 '22 21:10

Tony R


As people have said, these aren't really "patterns", and are reasonably specific to Groovy, but another two uses of Closures are:

1. Composability

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

2. Currying

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
like image 35
tim_yates Avatar answered Oct 16 '22 22:10

tim_yates


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.

like image 41
Geli Avatar answered Oct 16 '22 22:10

Geli