锻造坊 - Ruby on Rails 评估

作者:Reuven M. Lerner

几年前,在互联网泡沫的顶峰时期,咨询工作的电话响个不停。我和我的员工们争先恐后地完成人们向我们抛来的所有项目。在这场繁荣之中,很明显几乎每个项目都有相似的特点,而且我们花费时间和(客户的钱)在每个新项目中重新发明轮子。我们开始寻找方法,以便我们可以在不同的项目中重用代码,或至少是技术。我们认为,这将使我们不仅成为更具竞争力的企业,而且还会使我们的日常工作更有趣。毕竟,从事每个项目中新的和不同的元素,而不是创建另一个用户组权限系统,更有趣。

我们很快放弃了通用代码系统的计划,部分原因是其他开发人员不仅解决了许多这些问题,而且还在开源许可证下发布了他们的解决方案。因此,多年来,我们使用 Web 开发框架完成了各种不同的项目,其中许多项目我在早期的《锻造坊》版本中描述过。

但是,正如任何使用过此类框架的人所了解的那样,没有免费的午餐。几乎每个框架都试图让你以特定的方式做事,做出自己的一系列权衡,这些权衡可能(或可能不)适合你想要开发解决方案的方式。多年来,我使用过许多这样的框架,虽然我喜欢其中的各个部分,但我觉得它们都没有让我以我想要的方式表达自己。

因此,我也是众多开发者之一,他们对这个领域相对较新的事物越来越兴奋,它就是 Ruby on Rails。正如我们在过去几个月中看到的那样,Rails 是一个框架,它提供了许多不同的功能,包括对象关系映射器、MVC(模型-视图-控制器)设计方法、集成的模板系统和内置的测试支持。

Rails 自首次发布以来的一年左右时间里变得非常流行,尽管它仍然有些粗糙,但其势头是不可否认的。此外,Rails 现在变得如此流行,以至于其他框架也纷纷涌现,声称自己是类似 Rails 的框架,或者具有许多“就像 Rails”或“比 Rails 更好”的功能。

为什么这么多人对 Rails 感到兴奋?更重要的是,您应该考虑在您的下一个 Web/数据库项目中使用它吗?最后,它迫使开发人员做出哪些权衡,这些权衡会如何影响您的决策?

Rails 之前

自从 Web 应用程序这个词还只是描述发送电子邮件的 CGI 程序,而不是一个价值数十亿美元的产业时,我就开始开发 Web 应用程序了。我使用的每个框架都带来了一些东西,并且在一种或多种方面使我更容易开发应用程序。与此同时,每个框架都让我对其期望我为了使用该系统而做出的权衡感到沮丧。

例如,Mason 是我最早使用的 Web 开发框架之一,它的灵活性和易用性让我感到非常满意。Mason 是用 Perl 编写的,它被设计为最容易与 mod_perl 和 Apache 一起使用。多年来,安装和配置已经变得非常简单,前提是您的服务器上已经有一个可用的 Apache 和 mod_perl 副本。此外,Mason 与 CPAN 上提供的许多 Perl 模块以及 Perl 社区多年来创建的成熟而强大的开发工具完美集成。当我要用 Perl 创建一个在线系统时,Mason 绝对是我首先想到的工具。

但是,Mason 一直让我感到沮丧的是,系统附带的组件数量很少。当然,我可以创建一个处理用户帐户的系统,甚至可以创建权限和组的系统。但是,我真的想为我做的每个项目从头开始编写这样的代码吗?此外,虽然 Mason 的模板对于开发人员来说非常具有表现力,但它们包含大量的 Perl 代码和不寻常的结构,这可能会吓到或让非技术开发人员感到惊讶。

因此,我被 OpenACS 所吸引,OpenACS 是一个开源社区系统,它的追随者比 Mason 少得多。然而,OpenACS 模板系统将每个查看的页面分为两个组件,一个用 Tcl 编写,另一个用修改后的 HTML 形式编写,两者之间有指定的“契约”。此外,OpenACS 还附带了一个标准数据模型,旨在供系统中的所有不同应用程序使用。您无需担心创建注册模块,因为系统标配了一个注册模块。您也不需要创建论坛、网络日志或日历,因为这些也在标准系统中。

集中式的标准数据模型和一组管理应用程序当然很吸引人;然而,OpenACS 也有其自身的问题。也许最大的问题是 OpenACS 实现其数据模型的怪异方式,它使用关系数据库来跟踪层次结构和对象。这个系统具有很大的智力吸引力;关系数据库速度快、稳定且廉价,而面向对象编程使建模多种类型的数据变得更容易。但是,两者的结合意味着创建即使是一个简单的 OpenACS 应用程序也可能非常复杂。此外,随着 OpenACS 社区的壮大,数据模型变得越来越难以保持小巧,因为每个人的需求都略有不同。

我还研究了 Zope,这是一个主要用 Python 编写的 Web 开发框架。Zope 拥有一个庞大而强大的社区,并且 Zope Corporation 仍在继续开发和增强它。Zope 具有许多吸引人的功能,包括极其强大的开发环境、可以单独添加和升级的模块化“产品”,以及复杂的用户、角色和权限系统。Zope 还率先提出了对象发布的概念,其中 URL 描述了应该在特定对象上调用的方法。因此,URL /Foo/bar 意味着我们正在调用 Foo.bar,通过 HTTP 请求传递输入,并通过 HTTP 响应接收任何输出。

关于 Zope 最常听到的抱怨是它学习起来很复杂。这在某种程度上是真的;我花了一些时间才发现自己理解了所谓的“Zope 禅”。此外,许多我期望是直接的事情需要一些编码技巧才能正确工作——这可能反映了我的编码风格,但似乎也是 Zope 的一些设计决策以及对象在 Zope 中普遍使用方式的产物。

早期,Zope 的设计者决定通过构建自己的面向对象数据库来避免与关系数据库相关的问题。一方面,这使 Zope 比其竞争对手具有许多巨大的优势,包括撤消系统更改的能力、内置权限以及与 Zope 中的数据类型完美映射的存储系统。但是,考虑到关系数据库的速度和普遍性,SQL 也是必要的。因此,Zope 提供了连接和使用关系数据库的能力,使用其 DTML 模板语言的一个版本。

但这意味着许多 Zope 产品——当然也包括我使用过的所有产品——都必须协调关系数据库和对象数据库。这通常不是处理事情的太糟糕的方式,但我总是最终想知道为什么我的生活需要如此复杂。而且,尽管它非常复杂,但我经常发现自己一次又一次地创建相同类型的创建-更新-删除方法和模板。

Rails 的适用之处

因此,Ruby on Rails 填补了我长期以来为 Web 开发人员看到的许多空白,这应该不足为奇。话虽如此,我上面的描述也应该清楚地表明,如果 Rails 要继续取得成功,我认为它应该走向何方。

Rails 最吸引人的地方之一是开发人员可以快速轻松地创建与关系数据库对话的代码。虽然我远未被 15 分钟内可以完成的操作演示所说服,但我的经验证实,这些演示非常真实。这是因为 Rails 假设您将按照其约定创建数据库表,例如复数表名、名为 id 的 ID 字段以及以 _at 结尾的时间/日期字段。

如果您遵循这些约定,您将发现您只需编写极少量的代码即可处理许多标准情况。实际上,您可能会发现自己为创建的许多模型对象编写了几行代码,因为 Rails 中的 Active Record 映射器几乎为您完成了所有工作。

这意味着 Rails 应用程序所需的大部分工作都在控制器(即,其方法通过 URL 公开的对象)和视图(即,Ruby-HTML 混合模板)上。每个控制器方法都可以生成自己的纯文本、HTML 或通过视图目录中同名模板的输出。甚至还有一个内置的 Rails 函数用于向用户发送文件,允许您设置二进制文件的下载,而无需担心指定 MIME 类型和文件名的语法。

Zope 的拥护者无疑会说,这些后来的功能在 Zope 中可用,并且已经存在多年了。这是真的——但是对于新手来说,弄清楚如何使用它们以及它们的位置可能会非常困难。通过为大量活动提供合理的默认值,然后允许开发人员更改这些默认值,Rails 设法使简单的情况变得非常容易,而困难的情况仅变得中等困难。此外,Rails 附带的脚手架生成器提供了足够的基本初始控制器和模板集,使人们可以开始工作,而无需花费数小时创建和修改各种代码文件。

由于这些智能默认值,新的 Rails 开发人员在开始创建应用程序之前必须掌握的对象和方法数量有限。这与我描述的所有其他框架形成鲜明对比,这些框架需要理解相当多的对象和方法,以及它们如何组合在一起,才能高效地工作。诚然,Rails 的规模和复杂性都在增长,并且它面临着获得我们在更成熟的框架中看到的一些臃肿的风险。到目前为止,Rails 已经设法避免了许多这些问题和复杂性,并且开发人员似乎致力于尽可能保持简单。

考虑 Rails

正如我在上面写的那样,每个 Web 开发框架都做出了自己的一系列设计权衡。Rails 缺少什么才能使其变得更好?在考虑是否为正在开发的应用程序使用 Rails 时,您应该牢记什么?

首先,使用 Rails 需要接受 Ruby 语言。在使用 Rails 之前,我已经关注 Ruby 一段时间了,并且我越来越喜欢它。然而,毫无疑问,许多程序员会讨厌 Ruby 的元素,从语法到对象模型。在第三方附加库方面,Ruby 也比 Perl 和 PHP 不成熟,这意味着您可能需要自己编写一些专门的例程,而不是依赖社区的支持。最后,Ruby 缺乏真正的 Unicode 支持,这意味着许多多语言网站暂时无法使用它。

但是,如果您愿意将 Ruby 视为 Web 开发的语言,您应该使用 Rails 吗?我认为,开发团队越小,项目越有雄心壮志,您就越有可能从 Rails 中受益。非常小的项目不需要 Rails 所需的开销,并且它们可能最适合使用 CGI 程序和 PHP。但是,一旦您需要一个包含多个表的关系数据库,您就很可能从使用 Rails 中受益。

然而,Ruby 和 Rails 都是为小型程序员团队设计的,甚至也为独自工作的程序员设计的。如果多个人要成功地在一个 Rails 项目上工作,则需要程序员们高度自律,以确保没有人修改属于其他人职权范围内的文件。每个 Rails 应用程序都驻留在单个目录中的事实可能会增加这种混乱的可能性。

因此,大型项目可能会受益于一些更大的框架,例如 Zope——甚至近年来发布的许多基于 Java 的项目之一。我对 Java 最大的不满是它相对笨重且速度慢,尤其是与 Perl、Python 和 Ruby 等语言相比时。但是,当您与许多其他程序员一起从事大型项目时,拥有更多编译时检查、显式声明和 Ruby 等语言中缺少的安全措施可能是一个优势。

当考虑将 Rails 作为平台时,您可能还需要考虑您的 Web 设计师的成熟度。有些人喜欢在模板中处理代码的想法,而另一些人则害怕它,甚至可能会擦除或更改代码。我仍然认为 ZPT 和 OpenACS 模板是更好的模板系统,所以我对最近宣布的 Liquid 感到鼓舞,Liquid 是一个类似于 PHP 的 Smarty 的 Rails 模板系统。过去 Smarty 给我留下了深刻的印象,我认为这可能有助于加快将 Rails 引入大型、成熟的 Web 商店。

每个 Rails 应用程序都使用单个纯文本文件目录的事实既有优点也有缺点。一个主要的优点是所有内容都可以轻松存储在 CVS 或类似的version-control 系统中;在新位置安装应用程序可以像检出代码一样简单。但是,这种方法意味着,像 OpenACS 包和 Zope 产品一样,在同一服务器上运行同一应用程序的多个实例有点困难。我们总是可以创建 Rails 应用程序目录树的多个副本,但似乎不可能拥有同一软件包的多个实例。

正如我上面提到的,我最初非常被 OpenACS 吸引,因为它具有单一、标准化的数据模型。我现在明白,这种沉重的集中式数据模型几乎总是会不足,但我仍然想知道为什么 Rails 没有附带任何通用的内置权限或注册集。我想,答案是越来越多的 Rails 插件,其中有几个注册系统可以集成到现有的 Rails 应用程序中。我仍然希望看到在这方面有更多的标准化,但这在目前可能已经没有希望了。

最后,Rails 与所有其他环境共享的一个问题是遗留代码问题。Rails 是如此新颖和与众不同,这是否意味着它的采用将迫使我们放弃我们已经完成的工作?可能,但不一定。我没有用 Ruby 重写成熟的 Perl 库,而是简单地使用 XML-RPC 编写了一个包装器。Ruby 有一个易于使用的 XML-RPC 客户端,我在我的 Rails 应用程序中使用它来联系 Perl 代码。这工作顺利而轻松,这意味着我可以同时从 Rails 和 CPAN 中受益。Rails 允许开发人员覆盖其数据库命名约定的事实也意味着它可以与现有数据库一起使用,而不是迫使用户创建符合 Rails 约定的新数据库模式。

结论

有些人欢呼 Rails 的到来是 Web 开发新时代的开始。的确,我认为 Rails 为我们对 Web 开发框架的期望设定了新标准。开发人员不再会相信,创建“hello, world”程序,甚至处理基本数据库操作,应该需要几行以上的代码。

此外,Rails 开始让开发人员相信,通用约定有助于快速、无 bug 的开发。开发人员花了多年时间才同意垃圾回收语言是对 malloc() 的改进,我们也花了同样长的时间才同意约定优于配置文件。但是 Rails 的流行可能意味着我们越来越准备好接受这种变化。

虽然没有完美的 Web 开发框架,但我相信 Rails 已经为我在过去十年中发现自己编写的许多应用程序找到了最佳点。Ruby(语言)和 Rails(框架)都还在成熟——但如果它们作为相对不成熟的工具就是这样,我迫不及待想看看它们最终成熟时会是什么样子。

本文资源: /article/8693

Reuven M. Lerner,一位长期的 Web/数据库顾问,目前是伊利诺伊州埃文斯顿西北大学学习科学专业的博士生。他和他的妻子最近庆祝了他们的第三个孩子,一个男孩的出生。

加载 Disqus 评论