Rails 案例研究

Rails 案例研究

Rails 开发与 Java 编程的比较
developerWorks
文档选项
将此页作为电子邮件发送
将此页作为电子邮件发送
未显示需要 JavaScript 的文档选项

级别: 中级
Bruce Tate ( [email protected]), CTO, WellGood LLC
2007 年 4 月 24 日
Ruby on Rails 开发和 Java™ 开发有着本质的不同。在 跨越边界 系列的最后一期中,Bruce Tate 将概述使用 Rails 从头开发一个复杂、可伸缩的 Web 站点时所发现的二者的主要差异。
Rails 开发人员常常把 Java 开发人员看作是沉闷而劳碌的老古董。而 Java 崇拜者则常常认为 Ruby on Rails 只是一个玩具,根本不能用于任何严肃的软件开发。作为一名对这两种技术都有着广泛使用经验的顾问,我认为真实的情形介于这两种观点之间。由于 跨越边界 系列文章即将结束,因此我打算对它们再作一次比较。本文并非考察某种特殊的技术或语言,而是主要介绍我当前正在从事的项目,并将它与我以前从事的 Java 项目进行比较。另外,我建议您阅读 “跨越边界”系列的前几期文章,对相关主题作更深入的了解。这种直接的说明可让您在二者之间权衡利弊,并可能使您在数据库 Web 应用程序 green-field 的开发中通过使用 Rails 获益。
业务问题
关于本系列
跨越边界 系列文章中,作者 Bruce Tate 提出这样一种观点,当今的 Java 程序员们可以通过学习其他方法和语言更好地武装自己。自从 Java 技术明显成为所有开发项目最好的选择以来,编程前景已经发生了改变。其他框架影响着 Java 框架的构建方式,从其他语言学到的概念也可以影响 Java 编程。您编写的 Python(或 Ruby、Smalltalk 等语言)代码可以改变编写 Java 代码的方式。 本系列介绍与 Java 开发完全不同的编程概念和技术,但是这些概念和技术也可以直接应用于 Java 开发。在某些情况下,需要集成这些技术来利用它们。在其他情况下,可以直接应用概念。具体的工具并不重要,重要的是其他语言和框架可以影响 Java 社区中的开发人员、框架,甚至是基本方式。
不论是 Ruby on Rails 框架还是任何 Java 框架都不能解决所有问题。为了提高成功的几率,需要长期、细致地考察业务问题,理解周围的各种假定情况,以及了解您的团队。只有这样才能选出正确的语言来进行开发。
去年,Arvato Systems 聘请我带领团队构建 ChangingThePresent.org,它是一种新平台,用于将非赢利性团体和捐赠人组织在一起。与很多 Internet 公司一样,我们向客户展示了可购买的实际产品。与其他公司不同的是,这些 “产品” 指的是提供机会,比如:一名癌症研究员一小时服务收费 50 美元、帮助盲人收费 30 美元,或者保护一英亩雨林一个月收费 20 美元。我们面临两大挑战:一份很紧凑的时间表和长期的复杂性。
开发工作从九月份开始,要求必须在十一月份之前建立起一个站点,以便有机会赶上圣诞节期间的通信量高峰。(最终我们超出了十一月份这个期限两星期。)在其他开发语言中,基于 Java 的解决方案可能要花费 6 到 18 个月才能完成这一任务。因此生产力是一个很重要的考虑因素,这与 Java 部署思想相悖。
通过对竞争对手和项目的考察,我们了解到:我们希望能够每天给站点带来几百万次点击的通信量。而我们需要每天有几十万次成功的点击,因此可伸缩性也是一个考虑因素。这与 Java 部署思想相符。
最后,我们了解到:发布初始站点只是一个开始。我们只实现了总体规划的百分之三。因此我们所选的技术需要根据复杂性和负载作出一些调整。我认为 Ruby 语言在复杂性方面会更易于调整,因为它提供了对更高级语言和特性(如开放类)的支持,以及具有更少配置需求和更简单、集成化编程模型的 Rails 框架。
虽然我们面临着时间和可伸缩性方面的挑战,但是也拥有一些其他的有利因素。我们拥有一张完全空白的候选名单:可以选择想要的任何技术、任何团队。可以定义项目、培训和全部的技术。我们可完全自由地作出选择。
Java 语言是一种优秀的通用语言。它总是应用于新的技术领域,如嵌入式系统和移动设备。Java 语言在广泛关注的集成方面也表现优秀。它具有高性能、流行并受到平台的良好支持。但是正如您在本系列中所了解到的那样,Java 语言并不是用于数据库支持的 Web 应用程序的 green-field 开发的最佳选择(请参阅文章 “ 动态类型语言中的 Web 开发策略”)。
相比之下,Ruby on Rails 框架则是新的。并没有很多人使用 Rails 开发高通信流量的站点,并且几乎不存在什么使用 Rails 多年开发项目的经验。但它仍然是一种高生产力的数据库支持的 Web 应用程序开发的框架。最后,尽管我们对 Rails 缺乏开发长期项目的经验和并未得到广泛部署有所顾虑,但那份紧凑的时间表驱使我们选择了 Ruby on Rails。
作出这个决定之后,我们发现招募项目人才非常容易。我们还发现早期的生产力优势非常显著 ―― 甚至比预期的还要好。我们确实遇到了一些早期的稳定性问题,因此加强了测试工作的力度(请参阅文章 “ 在集成框架中进行测试,第 1 部分” 和 “ 在集成框架中进行测试,第 2 部分”)。此后稳定性得到了极大的改进。




回页首


原理
每个框架设计者都使用一组假定来构造该框架的重写原理。学习遵守该原理的约束可使您愉快地进行编程,而挑战这些约束则会使您的编程受挫。Rails 框架和 Java 框架拥有很多不同的原理。
Rails 是一种集成框架,需要使用高度利用 Ruby 语言的动态本质(请参阅 “ Ruby on Rails 的秘笈是什么? ”)。Rails 开发人员强调框架的生产力特性而不是工具特性,并且常常将 Web 架构看得非常简单,在本系列的前几篇文章中您已了解到这一点。Java 设计者通常必须分块地组合开发环境,独立地选择持久性、Web 和集成层。他们通常严重地依赖工具来简化核心任务。Web 架构设计趋向于较为复杂。
完全集成
Java 框架往往是解决一个小问题(比如持久性或查看组织),而 Rails 则是一个集成环境。Rails 开发人员的优势在于不必解决与许多不同框架集成的问题。大多数 Hibernate 开发人员陷入了过早关闭与 Java Web 框架之间的连接的陷阱。Rails 视图框架是从头构建的,以便与 ActiveRecord 集成(Rails 持久性框架)。当您考察用于 Web 服务、配置和插件的 Rails 框架时也会发现类似的经验。Java 编程支持各种不同的框架,对于所有这些框架使用不同的集成策略。
Java 开发人员的优势在于选择。如果您需要从头构建一个框架,则可能要考虑使用基于 SQL 的解决方案用于数据库集成(如 iBATIS 或 Java 编程中基于 JDBC 的包装框架之一)。反过来,如果要使用一种古老的模式进行编程,则可能要使用对象关系映射框架(如 Hibernate)。相比之下,如果您使用 Rails,则拥有一个主要选择:ActiveRecord。这意味着 Java 框架提供了更多的选择,有时能提供更好的集成开发项目的解决方案。但是由于我们要开发一个 green-field 项目,因此选择算不上是一个问题。
一种动态语言
Rails 原理的下一个主要部分是动态编程语言(请参阅文章 “ Java 模型以外的类型策略”)。Java 工具往往可以有效地使用 Java 类型模型提供的额外信息。工具可以识别错误和有效地重构代码。Rails 还可有效地利用编程语言的优点。Ruby 是一种构建特定于域的语言(DSL)的理想语言(请参阅文章 “ 活动记录和 Java 编程中特定于域的语言”)。Rails 集中使用 DSL 来完成从构建模型对象之间的关系到指定自定义组件(如状态机器或可上传的图像)的所有工作。动态语言常常更加简洁,因此 Rails 项目比 Java 项目要简练得多,可让用户更简练地表达代码和配置。在 ChangingThePresent.org 项目中,我们发现技术顶尖的程序员可达到更高的生产力,但是我们确实需要招募经验更丰富的开发人员。我对这种妥协非常满意。
传统的 Java 程序员对 IDE 有着近乎虔诚的热爱,造成这一现象有充分的理由。IDE 提供了语法的完整性检查、修正了小错误并提供了增量编译以便更快地完成编码、编译、部署和测试这样的周期。最近几年来,开发环境开始更好地利用编译循环和静态类型提供的信息。IDE 现在编辑抽象语法树(AST),而不是(或者同时)编辑代码的文本表示。这一策略允许使用强大的代码重构工具,而使用静态类型语言的同样方法来实现此功能则困难得多。
静态类型确实能更好地使用工具,但是也存在缺点。强制使用静态类型通常需要编译器,而编译步骤必然会降低生产力。使用 Rails,我可以更改一行代码并重新加载浏览器,就可立即看到更改的结果。与 Java 开发人员相比,大多数 Ruby 开发人员只使用一种很好的编辑器。TextMate 是最流行的 Ruby on Rails 编辑器,它提供了语法突出显示、代码完整性检查,以及一些频繁使用的结构的良好的模板支持。而当发现可将所有简单的基于 Ruby 的脚本(用作基本的 Rails 工具包)放入编辑器中时,您会更加喜出望外。与纯粹的调试器不同的是,我可以使用断点脚本,该脚本可停止特定的应用程序,进入一个 Ruby 解释程序,我可在其中调用方法、检查变量的值,以及甚至在恢复执行之间修改代码。
简单的架构
传统的 Web 端 Java 架构包括:一个用于域对象和数据访问对象的层、一个提供业务级 API 的外观层、一个控制器层和一个视图层。此架构比典型的 “模型-视图-控制器” 架构(使用 Smalltalk 语言最早创建)稍微复杂一些。相比之下,Ruby on Rails 包括一个使用 ActiveRecord 设计模式的模型层、一个控制器层和一个视图层。我们喜欢易于获得的 Rails 方法。它更加简练并且带来额外的复杂性和错误的机会更小。
惯例优先原则
Java 框架通常可以自由地使用 XML 配置,而 Rails 主要使用惯例来避免可能的配置。在程序员必须指定配置的位置,Rails 通常依赖 Ruby(常常以 DSL 形式)来提供配置。对于 green-field 开发,我发现惯例优先于配置是很有意义的。该策略为我省去了很多行代码,更简化了必须编写的代码。估计我们所需的配置只有传统 Java 应用程序中所指定的十分之一。我们有时会损失一点灵活性,但这并不足以抵消使用此策略带来的节省。
总而言之,Rails 框架的原理适合解决 ChangingThePresent.org 项目中的问题。集成的各种工具让我可以利用框架实现更多的功能而无需自己进行过多的集成。“惯例优先原则” 为我节省了配置站点的时间。动态语言为经验丰富的开发人员提供了更多的能力和灵活性,同时也使他们能够利用更少的代码表达更强大的思想。该框架适合于我们团队的能力和要解决的业务问题。




回页首


持久性
Java 和 Ruby 语言的最流行的持久性框架可以比任何其他特性更好地阐明 Java 和 Ruby 经验之间的区别,Java 开发人员通常使用 Hibernate,它是一种对象关系映射框架。通过 Hibernate,您可获取现有的模型和模式并使用注释或 XML 表达二者之间的映射。Hibernate 类是简单传统 Java 对象(POJO),它的每个对象派生自一个通用的基类。大多数配置是显式的,使用注释、XML 或二者的某种结合。
而 ActiveRecord 是一种包装的框架,就是说每个类都是现有类的包装器(请参阅文章 “ 研究活动记录”)。ActiveRecord 根据关联表的内容(如表中每列的一个属性)自动地向模型对象添加特性。所有的类都从一个通用的基类继承。ActiveRecord 主要利用通用约定来推断配置。例如:
  • ActiveRecord 利用类名的复数形式来推出表名。
  • 主键的名称为 id
  • 列表的排序顺序由 position 字段决定。
对象关系映射是使用遗留模式(可能定义时没有考虑对象模型)时的最佳解决方案。但是当您能为应用程序显式地设计数据库模式时,您通常不需要映射框架了。我们将 ActiveRecord 看作我们的一个巨大优点。我们可以包含关系数据库,需要时转入 SQL 并在适当的时候退出。
迁移
Rails 迁移使我们能够用代码表示模式的两个版本之间的差别,和它们所包含的数据之间的差别(请参阅文章 “ Rails 迁移”)。对每个迁移都进行了命名和编号。可在任何时候恢复到任何版本。迁移有以下一些确切的优点:
  • 产生错误代码时可恢复到一个旧版本的模式。
  • 用代码而不是 SQL 来表达模式,更便于我们使用。
  • 在最大程度上与数据库独立。
但是迁移也有一些限制。如果两个开发人员同时创建迁移,则编号会出现混乱,所以我们必须手动处理。我们通过有效的通信来使这些问题最小化:团队成员构建需使用迁移的新模型时发出通知。但是这个模型依赖于团队的开发人员较少或迁移进展较慢的情况。
ActiveRecord 还有其他的限制,其中一些是故意作出的。Rails 的创建者认为:数据库的约束和组成应归入应用程序而不是数据库,这种思想带来了一些副作用。ActiveRecord 使用视图的情况不是很好:构建过程(克隆模式、复制测试数据并运行测试)并不能正确地进行复制。ActiveRecord 在使用参考完整性约束的某些场合也会出现问题,因为某些类型的关联可能连接到多个数据库表。跨越复杂模型进行预先加载很复杂,通常在连接多行时需要使用 SQL。继承也受到限制:使用 ActiveRecord 时,我被迫使用 单表继承 映射策略,而该策略并不总是最佳选择。(参见 参考资料)
所有的持久性策略都充满了妥协。我认为 ActiveRecord 实现了一组有效的妥协,常常选择了简单性。总而言之,ActiveRecord 和迁移是我们的积极推动。我们可以快速地构建解决方案,我们拥有足够的 SQL 访问权可在需要时改进系统性能。但是当 ActiveRecord 并不总能应对挑战时,最好将 Rails 应用于使用老旧模式的项目。一些替代的持久性模型正在出现,包括 RBatis,一种 iBATIS Java 框架的端口(参见 参考资料)。现在讨论 RBatis 的有效性还为时过早。




回页首


结束语
对于我的团队和项目来说,Ruby on Rails 被证明相当有效。我还不知道这个项目的最终规模如何,因为撰写本文时该系统才运行 3 个月。现在只是开始增加通信量。但是我们对生产力却很了解。我知道团队的预算比竞争公司(这些公司常常使用 Java 解决方案)的要低得多。我对我们的生产力也很有信心。
通过 跨越边界 系列,我向您介绍了 Java 领域以外的语言和解决方案。但程序员毕竟是技术人员。每个高明的技术人员的工具包中都应包含适用于每个解决方案的广泛的工具集。除工具外,本系列中介绍的观点也为您展示了一些其他思路。现在一些框架设计者甚至将 Seaside、Rails 中的技术甚至 JavaScript 应用于 Java 框架中。找机会进行同样的应用,继续 “跨越边界”。

你可能感兴趣的:(职场,Rails,案例,休闲)