1 命令链
Groovy 可以使你省略顶级语句方法调用中参数外面的括号。“命令链”功能则将这种特性继续扩展,它可以将不需要括号的方法调用串接成链,既不需要参数周围的括号,链接的调用之间也不需要点号。举例来说, a b c d
实际上就等同于 a(b).c(d)
。它适用于多个参数、闭包参数,甚至命名参数。而且,这样的命令链也可以出现在赋值的右方。让我们来看看应用这一新的语法格式的范例:
// 等同于:turn(left).then(right)
turn left then right
// 等同于:take(2.pills).of(chloroquinine).after(6.hours)
take 2.pills of chloroquinine after 6.hours
// 等同于:paint(wall).with(red, green).and(yellow)
paint wall with red, green and yellow
// 命名参数
// 等同于:check(that: margarita).tastes(good)
check that: margarita tastes good
// 闭包作为参数
// 等同于:given({}).when({}).then({})
given { } when { } then { }
不带参数的链中也可以使用方法,但在这种情况下需要用括号。
// 等同于:select(all).unique().from(names)
select all unique() from names
如果命令链包含奇数个元素,链会由方法和参数组成,最终由一个最终属性访问:
// 等同于:take(3).cookies
// 同样也等于:take(3).getCookies()
take 3 cookies
借助命令链方法有趣的一点是,我们能够利用 Groovy 编写出更多的 DSL。
上面的范例展示了使用基于 DSL 的命令链,但是不知道如何创建一个。你可以使用很多策略,但是为了展示如何创建 DSL,下面列举一些范例,首先使用 map 映射与闭包:
show = { println it }
square_root = { Math.sqrt(it) }
def please(action) {
[the: { what ->
[of: { n -> action(what(n)) }]
}]
}
// 等同于:please(show).the(square_root).of(100)
please show the square_root of 100
// ==> 10.0
第二个范例要考虑如何编写 DSL 来简化一个现存的 API。或许你需要把这些代码展示给顾客、业务分析师或测试员,有可能这些人并不是技艺非常精湛的 Java 开发者。我们将使用 Splitter
,一个 Google 的 Guava libraries 项目,因为它已经是一个良好的 Fluent API 了。下面展示如何使用它。
@Grab('com.google.guava:guava:r09')
import com.google.common.base.*
def result = Splitter.on(',').trimResults(CharMatcher.is('_' as char)).split("_a ,_b_ ,c__").iterator().toList()
对于 Java 开发者而言,这段代码很容易明白,但如果面对的是目标顾客,或者要写很多这样的语句,那就可能显得有些啰嗦了。再次提醒一下,DSL 的编写手段多种多样。利用映射和闭包来将它简化一下,首先编写一个辅助函数:
@Grab('com.google.guava:guava:r09')
import com.google.common.base.*
def split(string) {
[on: { sep ->
[trimming: { trimChar ->
Splitter.on(sep).trimResults(CharMatcher.is(trimChar as char)).split(string).iterator().toList()
}]
}]
}
然后找到原始范例中的这一行:
def result = Splitter.on(',').trimResults(CharMatcher.is('_' as char)).split("_a ,_b_ ,c__").iterator().toList()
替换成下面这行:
def result = split "_a ,_b_ ,c__" on ',' trimming '_\'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论