什么是委托对象?

时间:2016-08-21 18:54:52

标签: android gradle groovy

我目前正致力于编写gradle构建脚本。什么是委托对象以及何时使用它们?

class GroovyGreeter {
    String greeting = "Default greeting"
    def printGreeting(){println "Greeting: $greeting"}
}

def myGroovyGreeter = new GroovyGreeter()

myGroovyGreeter.printGreeting()
myGroovyGreeter.greeting = "My custom greeting"
myGroovyGreeter.printGreeting()

/*

The last Groovy feature we'll cover is that closures can have a delegate
object. Any variables or methods referenced in the closure that don't have a
local definition are then evaluated against the closure's delegate. Let's make
a closure that will access the property and method of our GroovyGreeter class.

*/

def greetingClosure = {
    greeting = "Setting the greeting from a closure"
    printGreeting()
}

//greetingClosure() // This doesn't work, because `greeting` isn't defined
greetingClosure.delegate = myGroovyGreeter
greetingClosure() // This works as `greeting` is a property of the delegate

请帮帮我。

1 个答案:

答案 0 :(得分:3)

什么是封闭代表?

当您将闭包的委托设置为另一个对象时,对闭包的范围内无法解析的属性/方法的任何调用都将由闭包的委托解决。在您的示例中,greetingprintGreeting未在greetingClosure闭包范围内定义

def greetingClosure = {
    greeting = "Setting the greeting from a closure"
    printGreeting()
}

因此,当您将此闭包的委托设置为GroovyGreeter

的实例时
greetingClosure.delegate = myGroovyGreeter

它们(成功)被此对象解析,因为它确实定义了具有这些名称的属性和方法。

何时使用代表?

当您希望DSL /构建器的用户能够使用任何名称调用方法时,它们通常用于DSL或构建器,并且在DSL中使用该方法的名称几乎就像一个额外的方法参数。以下使用构建器生成XML的示例

def writer = new StringWriter()
def xml = new MarkupBuilder(writer) 

xml.records() { 
    car(name:'HSV Maloo', make:'Holden', year:2006) {
        country('Australia')
        record(type:'speed', 'Production Pickup Truck with speed of 271kph')
    }
}

def records = new XmlSlurper().parseText(writer.toString())

创建构建器后我们要做的第一件事是调用records传递一个闭包参数。实际上records内的MarkupBuilder方法在MarkupBuilder中定义了一个带有闭包参数的方法,但所有未定义的方法都将使用Groovy's methodMissing feature路由到records

在传递给car的闭包中,我们调用了在编译时未定义的各种其他方法,例如: MarkupBuilderMarkupBuilder如何解决这些方法调用?因为此闭包的委托设置为 SELECT message_content, message_times_read FROM messages WHERE message_id = 1 实例。