David Pollak 在Beginning Scala中找到了一个有趣的案例研究,该案例研究了使用动态语言和解释语言的扩展项目问题。
我开始寻找一种以更简单,更直接的方式在我的大脑中表达代码的方法。我找到了Ruby和Rails。我感到解放了。Ruby允许我用更少的代码行来表达概念。与Spring MVC,Hibernate和其他“简化的” Java Web框架相比,Rails的使用要容易得多。使用Ruby和Rails,我必须在更短的时间内表达更多的想法。这类似于我从C ++迁移到Java时的解放...
随着我的Ruby和Rails项目扩展到几千行代码,并且当我向项目中添加团队成员时,动态语言的挑战就变得显而易见。
我们花费了一半以上的编码时间来编写测试,而我们看到的许多生产力提高都损失了测试编写。大多数测试在Java中是不必要的,因为大多数测试旨在确保在我们通过更改方法名称或参数计数来重构代码时更新了调用方。另外,我发现在团队中存在两到四个团队成员之间存在思想融合的团队时,Ruby的工作进展顺利,但是当我们尝试将新成员引入团队时,这种心理联系很难传递给新团队成员。
我一直在寻找一种新的语言和开发环境。我一直在寻找一种像Ruby一样具有表现力但又像 Java 一样安全和高性能的语言...
如您所见,作者项目扩展的主要挑战原来是测试开发和知识转移。
特别是,在第7章中,作者将详细解释动态和静态类型的语言在测试编写方面的差异。在“有力地杀死兔子:Dwemthy的台阶”一节中,作者讨论了特定Ruby示例的Scala端口:
为什么Lucky Stiff ...在Dwemthy的Array中引入了Ruby的一些元编程概念,其中,兔子与一系列生物战斗。N8han14更新了该示例以在Scala中工作 ...
与Ruby代码相比,Scala代码的库部分更加复杂。我们必须做很多工作来确保我们的类型正确。我们必须在DupMonster和CreatureCons类中手动重写Creature的属性。这比还要多method_missing
。我们还必须做大量的工作来支持我们的生物和武器的不变性。
另一方面,结果比Ruby版本强大得多。如果我们必须为Ruby代码编写测试以测试Scala编译器向我们保证的内容,那么我们将需要更多的代码行。例如,我们可以确定我们的兔子不会挥动斧头。为了在Ruby中获得这种保证,我们必须编写测试以确保|^
对Rabbit的调用失败。我们的Scala版本可确保该Creature只能使用为给定Creature定义的武器,而这在Ruby中需要大量的运行时反射。
上面的阅读可以使人认为,随着项目的扩大,测试写作可能变得非常繁琐。正如这个问题中提到的成功的非常大的项目的例子所证明的那样,这种推理是错误的(“ Python成功用于... YouTube”)。
问题是,项目的扩展并非真正简单。大型,长期存在的项目可以使用生产质量测试套件,专业的测试开发团队和其他重量级的东西来“负担”不同的测试开发过程。
与类似Dwemthy的Array之类的小型教程项目中的测试相比,Youtube测试套件或Java兼容性套件的寿命肯定会有所不同。