Groovy闭包和DSL

作者: 飞雪无情flysnow_org | 来源:发表于2017-02-27 10:01 被阅读382次

闭包是Groovy的一个非常重要的特性,可以说他是DSL的基础。闭包不是Groovy的首创,但是它支持这一重要特性,这就使用我们的代码灵活、轻量、可复用,再也不用像Java一样动不动就要搞一个类了,虽然Java后来有了匿名内部类,但是一样冗余不灵活。

初识闭包

前面我们讲过,闭包其实就是一段代码块,下面我们就一步步实现自己的闭包,了解闭包的it变量的由来。集合的each方法我们已经非常熟悉了,我们就以其为例,实现一个类似的闭包功能。

task helloClosure << {    //使用我们自定义的闭包
    customEach {
        println it
    }
}
def customEach(closure){    //模拟一个有10个元素的集合,开始迭代
    for(int i in 1..10){
        closure(i)
    }
}

在上面的例子中我们定义了一个方法customEach,它只有一个参数,用于接收一个闭包(代码块),那么这个闭包如何执行呢?很简单,跟一对括号就是执行了,会JavaScript的朋友是不是觉得很熟悉,把它当做一个方法调用,括号里的参数就是该闭包接收的参数,如果只有一个参数,那么就是我们的it变量了。

向闭包传递参数

上一节我们讲了,当闭包有一个参数时,默认就是it;当有多个参数是,it就不能表示了,我们需要把参数一一列出。

task helloClosure << {    //多个参数
    eachMap {k,v ->
        println "${k} is ${v}"
    }
}
def eachMap(closure){ 
    def map1 = ["name":"张三","age":18]
    map1.each {
        closure(it.key,it.value)
    }
}

从例子中我们可以看到,我们为闭包传递了两个参数,一个key,一个value,便于我们演示。这是我们我们就不能使用it了,必须要显式的声明出来,如例子中的k,v,符号->用于把闭包的参数和主体区分开来。

闭包委托

Groovy闭包的强大之处在于它支持闭包方法的委托。Groovy的闭包有thisObject、owner、delegate三个属性,当你在闭包内调用方法时,由他们来确定使用哪个对象来处理。默认情况下delegate和owner是相等的,但是delegate是可以被修改的,这个功能是非常强大的,Gradle中的很闭包的很多功能都是通过修改delegate实现的。

task helloDelegate << {
   new Delegate().test {
        println "thisObject:${thisObject.getClass()}"
        println "owner:${owner.getClass()}"
        println "delegate:${delegate.getClass()}"
        method1()
        it.method1()
    }
}
def method1(){
    println "Context this:${this.getClass()} in root"
    println "method1 in root"
}
class Delegate {
    def method1(){
        println "Delegate this:${this.getClass()} in Delegate"
        println "method1 in Delegate"
    }
    def test(Closure<Delegate> closure){
        closure(this)
    }
}

运行我们可以看到输出:

thisObject:class build_e27c427w88bo0afju9niqltzf
owner:class build_e27c427w88bo0afju9niqltzf$_run_closure2
delegate:class build_e27c427w88bo0afju9niqltzf$_run_closure2
this:class build_e27c427w88bo0afju9niqltzf in root
method1 in root
this:class Delegate in Delegate
method1 in Delegate

通过上面的例子我们发现,thisObject的优先级最高,默认情况下,优先使用thisObject来处理闭包中调用的方法,如果有则执行。从输出中我们也可以看到这个thisObject其实就是这个构建脚本的上下文,他和脚本中的this对象是相等的。

从例子中也证明了delegate和owner是相等的,他们两个的优先级是owner要比delegate高,所以对于闭包内方法的处理顺序是thisObject>owner>delegate。

在DSL中,比如Gradle,我们一般会指定delegate为当前的it,这样我们在闭包内就可以对该it进行配置,或者调用其方法。

task configClosure << {
    person {
        personName = "张三"
        personAge = 20
        dumpPerson()
    }
}
class Person {
    String personName    int personAge
    def dumpPerson(){
        println "name is ${personName},age is ${personAge}"
    }
}
def person(Closure<Person> closure){
    Person p = new Person();
    closure.delegate = p    //委托模式优先
    closure.setResolveStrategy(Closure.DELEGATE_FIRST);
    closure(p)
}

例子中我们设置了委托对象为当前创建的Person实例,并且设置了委托模式优先,所以我们在试用person方法创建一个Person的实例时,可以在闭包里直接对该Person实例配置,有没有发现和我们在Gradle试用task创建一个Task的用法很像,其实在Gradle中有很多类似的用法,在Gradle也基本上都是使用delegate的方式使用闭包进行配置等操作。

DSL

DSL(Domain Specific Language),领域特定语言,说白了就是专门关注某一领域专门语言,在于专,而不是全,所以才叫领域特定的,而不是像Java这种通用全面的语言。

Gradle就是一门DSL,他是基于Groovy的,专门解决自动化构建的DSL。自动化构建太复杂、太麻烦、太专业,我们理解不了,没问题,专家们就开发了DSL—Gradle,我们作为开发者只要按照Gradle DSL定义的,书写相应的Gradle脚本就可以达到我们自动化构建的目的,这也是DSL的初衷。

DSL涉及的东西还有很多,这里我们简单的提一下概念,让大家有个了解,关于这方便更详细的可以阅读世界级软件开发大师Martin Fowler的《领域特定语言》,这本书介绍的非常详细。

相关文章

  • Groovy闭包和DSL

    闭包是Groovy的一个非常重要的特性,可以说他是DSL的基础。闭包不是Groovy的首创,但是它支持这一重要特性...

  • 详解 groovy 的闭包(上)

    groovy 的闭包特点 在 groovy 中的闭包。groovy 中的闭包是一个开放的匿名代码块,可以接受参数,...

  • Groovy 闭包

    本文介绍了Groovy闭包的有关内容。闭包可以说是Groovy中最重要的功能了。如果没有闭包,那么Groovy除了...

  • Groovy语法简介

    Groovy简单语法: Groovy中的闭包:

  • 二、Groovy语法(二):闭包

    Groovy闭包 1、Groovy中闭包基础 1.1 闭包的概念闭包是被包装成对象的代码块,可以通过一个变量引用到...

  • 《Groovy极简教程》第9章 Groovy闭包(Closure

    《Groovy极简教程》第9章 Groovy闭包(Closures)

  • Groovy 闭包

    好久没动笔(键盘)了,发现自己变懒了。但是在实际的工作过程中,总是责怪自己没有动笔把自己之前的遇到的问题记录下来,...

  • Groovy 闭包

    闭包 闭包是一段可执行的代码块,类似于方法也可以传递参数;可在闭包中访问属性值,也就是说可以修改闭包作用域中的所有...

  • Groovy闭包

    闭包定义与调用 *动态闭包 this、owner、delegate闭包里面有3个重要的对象,把它们弄清楚了,才能对...

  • Gradle开发-Groovy入门

    #Groovy DSL 简单了解; Groovy 的基本概念; Groovy 的特性; Groovy 的优势 总结...

网友评论

    本文标题:Groovy闭包和DSL

    本文链接:https://www.haomeiwen.com/subject/vuvnwttx.html