【问题标题】:Groovy Builder supportGroovy 构建器支持
【发布时间】:2011-09-26 06:10:09
【问题描述】:

如何使用 groovy 构建器支持构建上述模式

emp = empFileFactory.root()
{
  emp(id: '3', value: '1')

  emp(id:'24')
  {
    emp(id: '1', value: '2')
    emp(id: '6', value: '7')
    emp(id: '7', value: '1')
  }

  emp(id: '25')
  {
    emp(id: '1', value: '1')
    emp(id: '6', value: '7')
  }

}

我正在尝试在 groovy 中构建上述结构,有人可以解释我如何实现这一点

【问题讨论】:

    标签: groovy closures dsl


    【解决方案1】:

    你可以做这样的事情(这没有错误处理,只为我不希望被调用的方法返回 null):

    // First define our class to hold our created 'Emp' objects
    @groovy.transform.Canonical
    class Emp {
      String id
      String value
      List<Emp> children = []
    }
    
    class EmpBuilder extends BuilderSupport{
      def children = []
      protected void setParent(Object parent, Object child){
        parent.children << child
      }
      protected Object createNode(Object name){
        if( name == 'root' ) {
          this
        }
        else {
          null
        }
      }
      protected Object createNode(Object name, Object value){
        null
      }
      protected Object createNode(Object name, Map attributes){
        if( name == 'emp' ) {
          new Emp( attributes )
        }
        else {
          null
        }
      }
      protected Object createNode(Object name, Map attributes, Object value){
        null
      }
      protected void nodeCompleted(Object parent, Object node) {
      }
      Iterator iterator() { children.iterator() }
    }
    

    然后,如果我们使用您所需的构建器代码调用它,如下所示:

    b = new EmpBuilder().root() {
      emp(id: '3', value: '1')
    
      emp(id:'24') {
        emp(id: '1', value: '2')
        emp(id: '6', value: '7')
        emp(id: '7', value: '1')
      }
    
      emp(id: '25') {
        emp(id: '1', value: '1')
        emp(id: '6', value: '7')
      }
    }
    

    我们可以像这样打印出“树”

    b.each { println it }
    

    然后看到我们得到了我们要求的结构:

    Emp(3, 1, [])
    Emp(24, null, [Emp(1, 2, []), Emp(6, 7, []), Emp(7, 1, [])])
    Emp(25, null, [Emp(1, 1, []), Emp(6, 7, [])])
    

    【讨论】:

    • 为了打印树我必须发出 db.each {println it}
    • 是的......我忘了把那个位粘贴到答案中:-/
    • 代码什么时候会出现 else if( name == 'root' ) { this }
    • 这一行:b = new EmpBuilder().root() {
    • no 方法 protected Object createNode(Object name, Map attributes) 有一个检查 else if( name == 'root' ) { this }
    【解决方案2】:

    您想实现扩展BuilderSupport 类,这很容易做到。有a pretty nice tutorial here。

    您需要实现一些方法,但命名应该是不言自明的:

    • createNode 创建一个节点(每个节点都有一个名称和可选的属性和/或值)
    • setParent 将一个节点分配为另一个节点的父节点

    差不多了。

    【讨论】:

    • 教程链接已损坏
    • @Jorge 现在修复了这两个链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 2018-06-26
    • 1970-01-01
    • 2010-10-03
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多