groovy 通用流畅构建器

标签 groovy metaprogramming dsl

我想创建一个简单的包装器,它允许将对象方法作为流畅的接口(interface)调用。我一直在考虑在创建时重写类的方法,但这似乎不起作用。这是否可以通过常规元编程以某种方式实现?

到目前为止我有这样的代码片段:

class FluentWrapper {

    def delegate

    FluentWrapper(wrapped) {
        delegate = wrapped

        delegate.class.getMethods().each { method ->
            def name = method.getName()
            FluentWrapper.metaClass."$name" = { Object[] varArgs ->
                method.invoke(wrapped, name, varArgs)
                return this
            }
        }
    }

    def methodMissing(String name, args) {
        def method = delegate.getClass().getDeclaredMethods().find { it.match(name) }
        if(method) {

            method.invoke(delegate,name, args)
            return FluentWrapper(delegate)
        }
        else throw new MissingMethodException(name, delegate, args)
    }

}

假设示例 Java 类:

class Person {
    void setAge()
    void setName()
}

我希望能够执行以下代码:

def wrappedPerson = new FluentWrapper(new Person())
wrappedPerson.setAge().setName()

我为此使用 Groovy 1.6.7。

最佳答案

这都是 Groovy,我使用的是 1.8.6(当前最新版本),但给出了这个 Person 类:

class Person {
  int age
  String name

  public void setAge( int age ) { this.age = age }
  public void setName( String name ) { this.name = name }
  public String toString() { "$name $age" }
}

这个 FluentWrapper 类:

class FluentWrapper {

  def delegate

  FluentWrapper(wrapped) {
    delegate = wrapped
  }

  def methodMissing(String name, args) {
    def method = delegate.getClass().declaredMethods.find { it.name == name }
    if(method) {
      method.invoke( delegate, args )
      return this
    }
    else throw new MissingMethodException(name, delegate, args)
  }
}

然后,您应该能够执行以下操作:

def wrappedPerson = new FluentWrapper(new Person())

Person person = wrappedPerson.setAge( 85 ).setName( 'tim' ).delegate

并且应该指定年龄和姓名

关于groovy 通用流畅构建器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9836277/

相关文章:

java - 如何在java中捕获groovy抛出的异常?

c++ - 元编程是否用于现实世界的 C++ 软件项目?

ruby - 如何使用 Ruby + Regex 编写内部自然语言 DSL?

c++ - 为领域特定语言部分解析 C++

javascript - 是否有任何用于解析/自动完成领域特定语言的 javascript 框架?

unit-testing - Grails getErrorCount()返回多个错误,如何获取错误列表?

hibernate - 避免在grails中加入表

java - 从 Java 检查 CGLib 代理的 Groovy 类

c++ - 使用 std::vector 类构造函数对 C 数组进行 Constexpr 包装

swift - 镜像未在 Swift 3 上获取基类