【问题标题】:Groovy and dynamic methods: need groovy veteran enlightmentGroovy和动态方法:需要groovy老手的启示
【发布时间】:2011-12-13 16:20:31
【问题描述】:

首先,我必须说我真的很喜欢 Groovy 以及它为 Java 开发世界带来的所有好东西。但由于我将它用于不只是小脚本,我有一些顾虑。

在这个Groovy help page about dynamic vs static typing 中,当您的代码中有拼写错误时,有以下关于不存在编译错误/警告的声明,因为它可能是对稍后在运行时添加的方法的调用:

取消所有静态类型和 首先编译时检查。但是许多 Groovy 资深人士会证明 它使代码更干净,更容易重构,而且,嗯,更多 动态的。

我非常同意“更动态”部分,但不同意更简洁、更容易重构:
对于其他两个语句,我不确定:从我的 Groovy 初学者的角度来看,这导致代码更少,但以后更难阅读,维护也更麻烦(不能再依赖 IDE 来查找谁在声明一种动态方法以及谁在使用这种方法)。

澄清一下,我发现阅读 groovy 代码非常愉快,我喜欢集合和闭包(解决复杂问题的简洁和表达方式)。 但是在这些情况下我有很多麻烦:

  • 'builder' 内不再使用 Map (Of Map (of Map)) 自动完成 无处不在
  • 混淆动态方法调用(你不知道是拼写错误还是 动态名称)
  • 闭包内部的方法提取更复杂(经常导致代码重复:'它毕竟只是一个小闭包')
  • 当您必须为子系统的方法编写闭包参数时,很难猜出闭包参数

不再通过浏览代码来学习:您必须改用文本搜索

我只能看到 GORM 的一些好处,但在这种情况下,动态方法是众所周知的,并且我的 IDE 知道它们(所以对我来说,它更像是系统代码生成而不是动态方法)

我很高兴向 groovy 老手学习他们如何证明这些好处。

【问题讨论】:

    标签: dynamic groovy maintenance


    【解决方案1】:

    确实会导致不同类别的错误和流程。它还使编写测试更快、更自然,有助于缓解错误问题。

    发现行为的定义和使用位置可能会有问题。尽管随着时间的推移 IDE 在这方面做得越来越好,但没有什么好办法。

    您的代码不应该更难阅读--主线代码应该更容易阅读。动态行为应该消失在应用程序中,并为需要了解这些级别的功能的开发人员适当地记录下来。

    魔法确实让发现变得更加困难。这意味着其他记录方式,尤其是人类可读的测试(比如 easyb、spock 等)和散文,变得更加重要。

    【讨论】:

      【解决方案2】:

      这有点老了,但如果有人来寻找有关该主题的一些想法,我想分享我的经验:

      现在我们在一个小团队(3 个开发人员)中使用 eclipse 3.7 和 groovy-eclipse 2.7,并且由于我们没有测试脚本,因此我们大部分的 groovy 开发都是通过显式使用类型来完成的。

      例如,当使用服务类方法时:

      void validate(Product product) {
        // groovy stuff
      }
      
      Box pack(List<Product> products) {
        def box = new Box()
        box.value = products.inject(0) { total, item ->
          // some BigDecimal calculations =)
        }
        box
      }
      

      我们通常会填写类型,这使 eclipse 能够自动完成,最重要的是,允许我们重构代码、查找用法等。

      这会阻止我们使用元编程,除了我发现支持并被 groovy-eclipse 检测到的类别。

      不过,Groovy 还是不错的,我们的很多业务逻辑都在 groovy 代码中。

      在使用 groovy 时,我们在生产代码中遇到了两个问题,这两种情况都是由于手动测试不当造成的。

      我们还有大量的 XML 构建和解析,我们会在将其发送到 web 服务等之前对其进行验证。

      我们使用一个小脚本连接到内部系统,该系统的使用非常受限(系统的其他部分不需要)。我使用完全动态类型开发的这段代码,使用元类的覆盖方法和所有这些东西,但这是一个例外。

      我认为 groovy 2.0(当然会出现 groovy-eclipse)和 @TypeChecked 对于我们这些将 groovy 用作“java++”的人来说会很棒。

      【讨论】:

        【解决方案3】:

        对我来说,重构有两种类型:

        1. 基于 IDE 的重构(提取到方法、重命名方法、引入变量等)。
        2. 手动重构。 (将方法移动到不同的类,改变方法的返回值)

        对于基于 IDE 的重构,我还没有找到一个 IDE 可以像使用 Java 一样出色地使用 Groovy。例如,在 Eclipse 中,当您提取到方法时,它会查找重复的实例以重构以调用该方法,而不是重复代码。对于 Groovy,这似乎不会发生。

        手动重构是我相信您可以看到重构变得更容易的地方。如果没有测试,但我同意这可能更难。

        关于更简洁代码的陈述是100% 准确的。我敢猜测,好的 Java 与好的 Groovy 代码至少是代码行数减少了 3:1。作为 Groovy 的新手,尽管我每天都会努力学习至少一种新的做事方式。对我的 Groovy 有很大帮助的一点是阅读 API。我觉得 Collection、String 和 List 可能是功能最多的,而且我用得最多的就是帮助我的 Groovy 代码真正成为 Groovy。

        http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html

        http://groovy.codehaus.org/groovy-jdk/java/lang/String.html

        http://groovy.codehaus.org/groovy-jdk/java/util/List.html

        由于您编辑了问题,我将编辑我的答案:)

        您可以做的一件事是告诉 intellij 您的对象上的动态方法:What does 'add dynamic method' do in Groovy/IntelliJ?。这可能会有所帮助。

        我使用的另一个技巧是在进行初始编码时输入我的对象,并在我完成后删除输入。例如,我似乎永远记不起它是字符串上的 .substring(..) 还是 .subString(..)。所以如果你输入你的对象,你会得到更好的代码完成。

        至于您的其他要点,我真的需要查看一些代码才能给出更好的答案。

        【讨论】:

        • 移动方法和更改签名由IDE很好地完成。我想念的其他类型的重构是从当前类中提取超类/接口。干净,你的意思是更有表现力还是更少混乱?因为有了所有的魔力,我发现代码不那么庞大但更难阅读,在我的 IDE 中有很多警告。当然 List 和 String 确实很时髦,但是有了一些好的库(例如 Guava),也有可能拥有好看的 Java :)
        • 我所说的干净是指更具表现力和更少混乱:) 你能分享一个你觉得难以阅读的东西的 GIST 吗?还有你用什么IDE?
        • 请查看我编辑的帖子中的项目符号列表。我用的是IDEA,号称对groovy有很好的支持。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-06
        • 2015-05-29
        • 2019-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多