Groovy可以方便的制作DSL,Command chain是支持它这么做的一个特性。
简单说,就是方法调用用约定好的规则省略括号和“ . ”等操作符,下面看例子
// equivalent to: turn(left).then(right)
turn left then right ** 这里省略了括号和点,一个方法间隔一个参数,当然,后面的方法是前面方法的返回值 **
// equivalent to: take(2.pills).of(chloroquinine).after(6.hours)
take 2.pills of chloroquinine after 6.hours 这里规则是相同的,参数不同
// equivalent to: paint(wall).with(red, green).and(yellow)
paint wall with red, green and yellow 这里展示多个参数的例子,即用逗号隔开
// with named parameters too
// equivalent to: check(that: margarita).tastes(good)
check that: margarita tastes good 参数为属性
// with closures as parameters
// equivalent to: given({}).when({}).then({})
given { } when { } then { } 参数为闭包
// equivalent to: select(all).unique().from(names)
select all unique() from names 没有参数的用空括号
// equivalent to: take(3).cookies
// and also this: take(3).getCookies()
take 3 cookies 如果一行共有奇数个词,则最后是属性调用
下面是一些实例:
show = { println it }
square_root = { Math.sqrt(it) }
def please(action) {
[the: { what ->
[of: { n -> action(what(n)) }] 创造DSL有很多方式,这里用map和闭包做的
}]
}
// equivalent to: please(show).the(square_root).of(100)
please show the square_root of 100
// ==> 10.0
下面例子是调用第三方包,或你自己实现的代码库来做DSL
@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() 调用了Google的guava库的splitter方法
@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()
}]
}] 继续用map和闭包做DSL
}
def result = Splitter.on(',').trimResults(CharMatcher.is('_' as char)).split("_a ,_b_ ,c__").iterator().toList() 正常调用
def result = split "_a ,_b_ ,c__" on ',' trimming '_\' 等价于这个