现在的位置: 首页 > 综合 > 正文

Groovy探索之Builder 二

2013年12月06日 ⁄ 综合 ⁄ 共 2934字 ⁄ 字号 评论关闭
                               Groovy探索之Builder 二
 
 
在前面的部分,我以MarkupBuilder为例介绍了如何使用Builder,通过它,我们可以看过了DSL编程的威力。当然了,既然看到了Builder功能的强大,我们就忍不住想自己创建一个Builder,来构建我们自己的DSL编程。
在Groovy语言中,我们有BuilderSupport来帮助我们创建我们自己的Builder,BuilderSupport为我们对创建Builder作了很大的简化。继承了BuilderSupport类以后,我们要实现如下的方法:
    protectedvoid setParent(Object parent, Object child)
    protected Object createNode(Object name)
    protected Object createNode(Object name, Object value)
    protected Object createNode(Object name, Map attributes)
    protected Object createNode(Object name, Map attributes, Object value)
    protectedvoid nodeCompleted(Object parent, Object node)
 
 
这些方法都是都是干什么用的呢?口说也无凭,我们就写一个例子,实际来看看这些方法到底是干什么用的。
class TestBuilder extends BuilderSupport{
   
    protectedvoid setParent(Object parent, Object child){
       
    }
    protected Object createNode(Object name){
        println'invoke createNode,input:'+name
    }
    protected Object createNode(Object name, Object value){
        println'invoke createNode, input-name: '+name+' value: '+value
    }
    protected Object createNode(Object name, Map attributes){
        println'invoke createNode, input-name: '+name+' attributes: '+attributes
    }
    protected Object createNode(Object name, Map attributes, Object value){
        println'invoke createNode, input-name: '+name+' attributes: '+attributes+' value: '+value
    }
    protectedvoid nodeCompleted(Object parent, Object node) {
        println'invoke nodeCompleted'
    }
 
 
 
}
 
 
上面的类是我们的一个Test类,每个方法都实现了在控制台打印自己的信息,告诉我们在什么时候调用了它,传入的参数是什么。
下面,我们就来测试它。
     def builder = new TestBuilder()
     
 builder.test()
 
 
首先,我们初始化了一个TestBuilder对象,然后来测试它。上面代码的结果为:
invoke createNode,input:test
invoke nodeCompleted
 
可以看到,当我们的builder对象调用一个没有参数的方法的时候,它会调用“createNode(Object name)”方法,在这个方法完成之后,再调用“nodeCompleted(Object parent, Object node)”方法。
 
我们接着往下测:
     def builder = new TestBuilder()
     
 builder.test'tom'
 
这次的test方法带一个参数“tom”,它的输出结果为:
invoke createNode, input-name: test value: tom
invoke nodeCompleted
 
可以看到,当我们的builder对象调用一个带有参数的方法的时候,它会调用“createNode(Object name, Object value)”方法,当然,在这个方法完成之后,再调用“nodeCompleted(Object parent, Object node)”方法。
 
现在终于看到了上面两个方法的不同,可能我们差不多也可以猜到其他方法的不同了。闲话少说,我们接着往下测:
     def builder = new TestBuilder()
     
 builder.test(type:'a')
 
 
这次测试的是test带有一个Map类型的参数,它的结果又如何呢?我们来看看它的打印结果:
invoke createNode, input-name: test attributes: ["type":"a"]
invoke nodeCompleted
 
结果可以看到,当我们的builder对象调用一个带有Map类型参数的方法的时候,它会调用“protected Object createNode(Object name, Map attributes)”方法,当然,在这个方法完成之后,再调用“nodeCompleted(Object parent, Object node)”方法。
 
最后,我们来完成最后一个测试:
     def builder = new TestBuilder()
     
 builder.test(type:'a','tom')
 
这次的测试,我们带有两者不类型的参数,一个是Map类型参数,一个是String类型参数。它的输出结果是什么呢?
invoke createNode, input-name: test attributes: ["type":"a"]
invoke nodeCompleted
 
 
正像我们猜到的那样,当我们的builder对象调用一个带有Map类型参数和一个带有String类型参数的方法的时候,它会调用“createNode(Object name, Map attributes, Object value)”方法,当然,在这个方法完成之后,再调用“nodeCompleted(Object parent, Object node)”方法。
 
总结:builder对象是根据不同的参数来调用它的不同方法,但调用完每一个方法之后,都会调用“nodeCompleted”方法。
注意:我在上面没有测试过“setParent”方法,有兴趣的你,不妨测试看看,看看它到底有什么用?
这一章节的内容到此结束,在下一章节,我们将创建一个可以实际使用的Builder例子,来具体看一看,在实际应用中,如何把我们这一章节的知识使用上的。

抱歉!评论已关闭.