关闭设计模式

时间:2012-04-03 23:48:27

标签: design-patterns language-agnostic groovy closures

这些天我正在学习设计模式。有很多关于编程设计模式的文档,但我对闭包设计模式很感兴趣。

我找到了关于Design Patterns in Java and Groovy的Venkat Subramaniam的演示文稿,并根据我自己的经验提取了一些涉及闭包和其他模式的演示模式。

执行方法

需要在操作之前和之后执行的一对操作。

def operations(closure) {
    println "Open"
    closure()
    println "Close"
}

operations { println "Operation" }

===> Open
===> Operation
===> Close

可插拔行为

在运行时指定对象的行为。

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

迭代器模式

允许顺序访问元素。

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

动态条件执行

创建并执行条件操作。

def greet(user, successClosure, failClosure) {
    if (isAdmin(user)) successClosure()
    else failClosure()
}

greet(user, { println "Hi Admin!" }, { println "Hello User" })

我想知道更多的闭包设计模式。有关于这个主题的参考吗?随意用您最喜欢的编程语言编写新模式。


更新

我写了一篇关于这个主题的帖子(Groovy和Ruby但内容相同):
Closure Design Patterns
Closure Design Patterns. Ruby Edition

3 个答案:

答案 0 :(得分:7)

我认为你对lambda /匿名函数的封闭感到困惑?

Closure是一个绑定变量的词汇上下文。简而言之,如果从函数内定义函数,则内部函数可以访问外部函数中定义的变量。在这种情况下,“词汇上下文”是外部函数。

Lambdas是没有变量赋值的函数。例如,在Ruby中,您可以将块传递给函数,并且函数可以仅使用yield关键字在内部调用它。在JavaScript中,您可以定义一个函数并同时将其作为参数传递。你的例子都是这样的。

First-class functions是另一回事,它是可以像常规对象一样传递的函数。您可以将它们作为参数传递给函数调用并保持对它们的引用。这就像Ruby的Proc。在JS中,所有函数都是一流的,所有函数都是对象。

在JavaScript中,我们可以用一个愚蠢的例子来说明所有3个:

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

所以,这会让你的问题变得混乱。闭包是一种语言特征,而不是设计模式。有许多设计模式,其实现可以使用闭包或lambda或modulo或构造函数或其他,正如您已经展示了这些示例。虽然这些都不是classical design patterns,所以我不确定我是否会打电话给他们。也许我会称他们为糖。

Java可以实现各种设计模式,但没有这些功能。很多这样的东西都是通过接口完成的,这是一种完全不同的语言特性。

答案 1 :(得分:1)

正如人们所说的那样,这些并不是真正的“模式”,而且非常适合Groovy,但是闭包的另外两种用途是:

1。可组合

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。讨好

def add = { a, b -> a + b }
def add2 = add.curry( 2 )

println add2( 3 ) // Prints 5

当然,这些可以结合起来:

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

答案 2 :(得分:1)

我同意其他的回答,因为谈论闭包设计模式并没有多大意义(特别是当你真的在谈论一流的功能时);)。我认为你真正想要的是如何在实现设计模式时使用诸如一流函数,lambdas和闭包之类的工具。虽然它特定于Groovy,但您可能会发现查看此页面很有用:http://groovy.codehaus.org/Design+Patterns+with+Groovy

例如,“Loan my Resource Pattern”显示了如何以与“Execute Around Method”模式非常相似的方式使用Closures,而“访问者模式”也是一个也充分利用了Closures并且不是' t列入您的清单。

相关问题