IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Rational  >

Rational Edge: Rails:专业 Web 网站的奢华路线

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

讨论

英文原文

英文原文


级别: 初级

Gary Pollice, 实践教授, Worcester Polytechnic Institute

2007 年 10 月 15 日

Journal icon 本文是上个月的介绍程序设计语言 Ruby 的文章的姊妹篇,介绍 Rails,一个构建于 Ruby 之上的框架,用于开发、维护和部署 Web 应用程序。

来自 The Rational Edge

插图 上个月,我详细地介绍了 Ruby 程序设计语言 —— 许多软件开发人员喜爱的动态语言。这个月,我要介绍用于构建 Web 应用程序的基于 Ruby 的框架,Rails。Rails 说明了框架的价值,动态语言,像 Ruby 的原动力,以及如何遵守配置的惯例来为开发人员形成许多优势。

寻求工作的更多价值

自从程序设计人员开始写程序,他们就一直寻找在程序中交付比投入工作量更多的价值的方法。在过去的五十年中,产生了许多关于如何这样做的理论。我们的确看到了高层次语言的演进。但是较低层次的语言之上的增量的改进没有使我们坐起来,拍着前额,说“喔”!甚至是在 90 年代中,属于“Very High-Level Language(非常高层次的语言)”(VHLL)类中的动态语言,也没有为了满足软件不断增长的需求而提供大部分人想要和需要的类型的收益。

我们已经促进了我们关于如何用可复用的框架,横切的技术,例如,面向方面的程序设计、基于组件的开发、面向服务的体系结构、模型驱动的架构等等,提高程序设计人员的生产力的思想。当适当地使用时,上面每种都会提供一些东西。虽然我们仍旧没有获得“无程序设计人员的程序”,但是有些人设想,我们已经在提高程序设计人员的生产力方面取得了进步。仍旧没有一种进步给予我们所需的 10-100X 的收益。

在继续下面之前,我想要说清除,在一般情况下,Rails 不为我们提供任何一种。然而,在构建 Web 应用程序的领域中,我已经看到 Rails 交付此类生产力的实例。

Rails 是什么?

Rails 是构建于 Ruby 顶部的框架,用于开发、维护和部署 Web 应用程序。框架可以松散地定义为能够为不同用途而修改的应用程序生成器或部分应用程序(在特殊领域中)。仅此而已!Rails 不是 Ruby 的通用扩展。它为专门的领域而设计 —— Web。Rails 基于一些基本原则,这些原则使得做一般的事情非常容易,并且能够做那些 Rails 基本范围之外的事情。Rails 向程序设计人员提供下面的,由其设计人员通过用非常少的程序设计必需品生成大部分典型的 Web 应用程序来建立的惯例。您可以通过生成熟练地写成的 Web 应用程序来使您的同事和经理吃惊,即使您是 Web 技术上的新手。 1

在许多文章中,Rails,还称为“Ruby on Rails”,它是 David Heinemeier Hansson,使用 Ruby 构建 Web 应用程序的丹麦 Web 应用程序开发人员的脑力劳动产物。他发现,在他构建应用程序的方式中有许多共同性。像许多好的开发人员一样,他开始寻找将其工作自动化的方式。他的工作的结果是 Rails 的首次发布。 2 Hansson 让 Rails 基于名为 Basecamp 的应用程序。 3 事实上,Rails 取自 Basecamp,并且通过抽象共同性并封装可变性来普遍化。这是在构建专用领域的语言时,我们一般使用的方法。

Rails 是拥有非常积极的开发人员和用户社团的开源项目。 4 如果您想要致力于 Rails,那么您就能够做到,并且与他人合作来增强它。但如果您仅仅想要用最少的工作构建专业的 Web 应用程序,那么您可以只在系统上安装 Rails 并开始工作。哦,是的,用 Rails 构建应用程序也很有趣!记得您在构建第一个有用的程序时是多么兴奋吗?我在第一次使用 Rails 时重获了这种感觉。

一个简单的实例

每个关于 Rails 的书籍或文章似乎都以一个简单的实例开始。我不打算详细介绍,但会向您展示来自最流行的 Rails 书籍,Thomas 和 Hansson 的 Agile Development with Rails 的一个实例的重点部分。 5 该实例是一个基本的在线购物网站。我们想要出售的产品有标题、描述、图像,和价格。在用了半个小时阅读并依照文本之后,我让应用程序处于我可以向数据库添加产品、编辑它们,并且删除它们的程度。应用程序遵循典型的 Model-View-Controller(MVC)架构并且 Rails 很容易地保持职责的分离,由于它自动地在分离的目录中生成适当的源文件(它们的用途很明显)。

我结束于的 Web 页面体看起来像图 1。现在我的目录中只有两个产品,但您可以看到关于该页面的一些东西。如果产品有图像,像我的杆机器人表演,那么它就出现了。描述的第一部分,以及任意内嵌的 HTML 标签显示出来了。每个产品后面都有三个链接,这样我们可以在显示产品、编辑项,或删除它时看到产品的样子。还有一个创建新产品的链接。我们明显地不准备让其问世,但我们可以开始与为我们的应用程序提供需求的项目涉众一起合作。这允许我们使用迭代的方法获得一些需求、实现它们,审查工作,并且为下一个迭代做出变更。

该图显示出拥有基本元素的初始的基于 Rails 的 Web 页面

图 1:产品目录管理页面

虽然我的 Web 页面看上去可能不惊人,但是我为此必须要做的事惊人的少。我通过在终端输入的命令的数量、我必须输入的 Ruby 代码的行数,以及我必须要写的 HTML 和内嵌的 Ruby(ERb)代码行的总量来度量我的工作。我通过复制来自 Thomas 和 Hansson 的书籍的下载的 Cascading Style Sheets(CSS)文件走了一些捷径,并且不在我的估值中计算该文件中行的数量。表 1 显示出我测量的结果。

表 1: 维护产品的工作


可计数项计数
命令8
Ruby LOC23
HTML 和 ERb LOC30

由于我对代码进行了一些实验,表 1 中的计数是近似的。然而,即使我写两倍的 Ruby 代码,我编辑器或在终端 shell 命令行中输入的代码行总量也少于 100 行。您可能会问,我真正从那很少的几行代码中获得了什么?考虑以下列表:

  • 填充了的 MySQL 数据库 6
  • 列出产品并允许对它们进行维护的 Web 页面
  • 结构良好的 MVC 应用程序
  • 确认产品目录中的字段(正数价格,非空的标题和描述)
  • 在不必须启动并停止服务器的情况下,我可以简单地在开发环境中修改并测试的应用程序。

我发现了我不必须要做的更令人兴奋的事:

  • 我不必写 SQL 代码,但我的应用程序由关系数据库支持的。
  • 我只有必须编写验证方法,确保价格是有效的。
  • 当数据库方案变更时,我不必创建特殊的代码来更新我的应用程序代码。

我不是 Web 应用程序开发人员。(由于我已经专注于软件工程的其他方面,所以当提到学习技术时,我已经处于曲线之后。在您有时间的时候有很多事要做。)我对 Ruby 和 HTML 只了解一点,但我足以用我的 Web 开发技能给学生留下印象。

Rails 原则

Rails 如何用对开发人员所需的如此少的工作来交付如此多的功能?可复用性的一个原则是普遍性和可复用性之间逆关系。如果您想要使组件或系统更可复用 —— 也就是说,拥有更大的可复用元素 —— 那么您将领域缩小为它适用的大小。这是我对 Rails 注意到的第一件事。它不是让您以您选择的任意方式构建 Web 应用程序的框架,而是,它支持 Web 应用程序开发的特殊方法。如果您依据方针,那么您可以获得极大量的复用。如果您偏离方针,那么您的复用量将减少。

那么,方针,或者 Rails 的原则是什么呢?原则没有许多,但它们贯穿于框架中。让我们在下几个部分中对每一个原则进行观察。

Model-View-Controller

Model-View-Controller 架构在软件开发人员之中很有名。它是早期的图形用户界面(graphical user interface,GUI)系统的基础,例如,出现在 Smalltalk-80 环境中。其概念简单,我们将该系统分离为三个不同的部分,如图 2 所示。

该图显示出 model-view-controller 架构的关系

图 2:Model-View-Controller 架构

MVC 架构将应用程序中的职责分离为三个不同的部分。模型负责维护应用程序的状态。它不检索并存储数据,它确保一致性。必须向数据应用的业务逻辑被封装在模型中。视图负责以一种或多种形式向用户展示模型。这允许模型根据用户的需要,以不同的方式显示。控制器负责确保其他的组件在适当的时刻做适当的事情。它接收用户的请求,并将它们分发到适当的地方去。MVC 对于许多类型的应用程序来说,是健壮,有效的架构,包括客户端/服务器 Web 应用程序。

当您遵照 Rails 惯例时,您完美地将关注分离为这三个组件。图 3 显示出示例应用程序的局部布局。您可以看到,应用程序对于每个组件都有分离的目录,并且对于任意支持这些组件所需的 helper 都有一个目录。

该图显示出示例应用程序文件夹和文件布局

图 3:局部的应用程序结构

在此,有一个单个的控制器,管理控制器。Rails 知道在浏览器中,根据当前的 URL 调用哪个控制器。在这种情况下,它是 URL 中 Web 服务器后面的那一部分。当我测试我的应用程序时,我将浏览器指向

http://localhost:3000/admin

,localhost:3000 连接到我在使用的服务器 —— 在这种情况下,Rails 带有的默认 WEBrick 服务器。我的 Rails 应用程序的控制器将请求导向 AdminController 类。如果您对该类包含的内容感兴趣,那么您可以查看本文附带的存档中的文件。您应该能够将该类中的大部分方法与图 1 中所示的 Web 页面上的链接相匹配。大部分真实工作是由 AdminController 继承的 ApplicationController 类完成的。如果您不了解细节,您不必担心。定义 AdminController 的文件,admin_controller.rb,是我的应用程序中较大的文件之一,我没有写一行代码。它完全是由 Rails 通过一个命令生成的。 7

Web 应用程序的视图是呈现给用户的 Web 页面。Rails 为您生成许多 Web 页面,但您仍旧需要了解一些基本的 HTML 和足够的 Ruby 来写出一点 ERb。Rails 中的视图没有什么独特的。您仅仅为每个操作创建一个 .rhtml(Ruby HTML)文件。

模型在我的应用程序中十分简单,数据库中只有一个用于产品的表,而一个产品有我前面提到的四个属性。我决定将图像 URL 作为可选属性,这样我不用验证它。所有其他字段都需要验证。随后是 product.rb 文件的完整文本。不是很大,对吗?

class Product < ActiveRecord::Base
  validates_presence_of :title, :description
  validates_numericality_of :price
  validates_uniqueness_of :title, :message => "We already have that in our catalog"
  
  protected
  def validate
    errors.add(:price, "must be worth something") if price.nil? || price < 0.01
  end
end

前三个 validates_ 方法是 Rails 的内嵌方法,对任何进入系统的产品都会自动地调用验证方法。我不得不添加核对,看看价格是否至少是 $.01。

您可能会怀疑,如果我不写任何 SQL,那么如何创建的产品表呢?Rails 有稍微不可思议的组件,称为 Active Record。 8 Active Record 是遵照了标准的 ORM 模型的对象关系映射(object-relational mapping,ORM)。它基本上是 ActiveRecord 设计模式的抽象实现。 9 换句话说,表映射到类,对象映射到行,而对象属性映射到列。Active Record,向一般的 Rails,采用了管理映射的标准方法。在不用做额外工作的情况下,它不支持完全的一般性。然而,如果您想要采用此标准默认职,那么您没有什么要做的事情。以下代码展示了创建表的文件:

class CreateProducts < ActiveRecord::Migration
  def self.up
    create_table :products do |t|
      t.column :title, :string
      t.column :description, :text
      t.column :image_url, :string
    end
  end

  def self.down
    drop_table :products
  end
end

我唯一写的代码行是三个 t.column.... 行。这些定义了标题、描述,和图像 URL 属性。要创建并配置数据库,我进行以下操作:

  1. 在命令行,我输入:

    mysqladmin -u root create depot_development

    这由我的开发数据库创建。

  2. 我在我的应用程序的根目录下输入以下命令:

    ruby script/generate model product

    这在数据库中创建 PRODUCT 表。它还创建了许多文件,包括上面显示的 product.rb 文件,以及应用程序的 db/migrate 目录中的名为 001_create_products.rb 的文件。该文件是先前列表中显示的。

  3. 我编辑文件添加三列定义。

  4. 我输入命令:

    rake db:migrate

    这在 PRODUCT 表中生成列。rake 是 Rails 使用的类似 make 的命令。

每次您需要更新数据库方案时,您以类似于上面顺序的方式生成了移植。每个移植文件开始的序列数都比前面的移植文件大,并且该数字符合位于数据库特殊表中的方案版本。现在您可以用最少的工作扩展数据库并回滚。Rails 为您做了。

好的,介绍了足够多的作为 Rails 应用程序的核心的 MVC。让我们转移到一些其他的原则上。

配置的惯例

我已经用行动说明了此原则。Rails 应用程序十分严格地遵守许多惯例。一些惯例像命名一样简单,而其他的更多关于应用程序的架构。Rails 对 Web 应用程序如何构建有非常清晰的概念,并且它使用给予该模型的默认值。关于默认值的假设令其可能生成比框架可能能够生成的大得多的应用程序部分。它还避免了让开发人员经历冗长的配置过程而为开发、测试,和部署设置适当的环境。有许多您可能修改来添加 MIME 类型或其他落在一般使用场景之外的信息的一些配置文件。您可能必须修改的唯一文件是为您的开发、测试,和部署环境说明关键参数的 database.yml 文件。当我创建我的应用程序时,根据默认值生成该文件,如下面清单中所示。

# MySQL (default setup).  Versions 4.1 and 5.0 are recommended.
#
# Install the MySQL driver:
#   gem install mysql
# On MacOS X:
#   gem install mysql -- --include=/usr/local/lib
# On Windows:
#   gem install mysql
#       Choose the win32 build.
#       Install MySQL and put its /bin directory on your path.
#
# And be sure to use new-style password hashing:
#   http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
  adapter: mysql
  database: depot_development
  username: root
  password:
  host: localhost

# Warning: The database defined as 'test' will be erased and
# re-generated from your development database when you run 'rake'.
# Do not set this db to the same as development or production.
test:
  adapter: mysql
  database: depot_test
  username: root
  password:
  host: localhost

production:
  adapter: mysql
  database: depot_production
  username: root
  password: 
  host: localhost

注意到,代码为每个环境使用三个分离的数据库。测试环境配置之上的注释指出了用 Rails 开发应用程序的附加特性。测试是 Rails 开发过程中的一等公民。当您根据惯例扩展并变更应用程序时,Rails 通过为您生成您将用 rake 功能运行的自动的测试来帮助您。测试在不妨碍开发环境和生产环境的情况下自动地在分离的环境中运行。

DRY 原则

Rails 应用程序中的最后原则是不要重复你自己(Don't Repeat Yourself,DRY)。好的设计者和程序设计人员将该原则作为大概的实践。他们知道,在一处做某件事情一次,另他们的设计更简单,并且令他们的工作更可维护。

当您遵照惯例时,遵照 DRY 原则的 Rails 组织并生成应用程序的方式很简单。当您了解了如何导航到一个 Rails 应用程序的代码基础时,您已经了解了您需要了解的其他遵照惯例的 Rails 应用程序。没有重复。每样东西都在一处,但所有的都有意义。

但它能成规模吗?

当我遇到表面上像 Rails 那样简单的东西时,我会怀疑它是否真正能够在真实的行业实力的环境中有效。我见过太多承诺提供很大生产力的工具。他们在“玩具”项目中看起来不错,但是当您将其应用于真实问题时就极其地失败。我已经读过相当多使用 Rails 的成功故事,但当我去年在大学中有了成功案例时,我真正地确信了。

我在伍斯特工业学院(Worcester Polytechnic Institute,WPI)的一个同事正在开发一个名为 Assistments 的智能辅导系统,在不同项目中各种层次上辅助教师和学生。在我所在的州,马萨诸塞州小学和高中学生在学习生涯中都必须通过一些列标准化测试,最终作为高中毕业的必备条件。这些测试,称为 MCAS 10 测试,在不同年级进行,以评价学生在关键学习领域中的能力。Assistments 11 辅导系统已经显示出在帮助学生学习必要技能方面是有效的。去年,伍斯特,MA 地区的少量学生使用了 Assistments 系统,但我的同事的 Assistments 团队不久就需要准备在更大范围进行部署。

Assistments 是典型的客户端/服务器 Web 应用程序。它不仅帮助老是和学生使用它,还支持开发新的学习方法并提供测量能力的研究员。到去年为止,Assistments 由超过 50,000 行的主要为 Java 代码的代码(lines of code,LOC)组成。代码中有许多由研究生和本科生开发了几年的包和类。不幸的是,开发团队中不是很连续,而代码非常的难于管理 —— 也就是,每天都越来越脆弱。该团队如何达到大规模首次亮相所需的质量?

有三个可能性。首先,我们可以继续尝试维护并扩展当前的系统。这被认为是不能长久的。其次,我们可以从头重写系统,或者尝试将现有的架构演进为我们需要的系统。这将是 Java 工作。最初,这是团队考虑采用的方法。

第三个可能性产生于一个工作在 Assistments 团队中的研究生建议用 Rails 重写系统时。如您想象的那样,他的同事和指导团队的教授都对此感到紧张。该学生花费了几周开发了拥有大多数现有 Assistments 系统的基本功能的核心应用程序。他写了不到一千行的代码来达到现在的程度。

团队被说服了。他们采用了可靠的开发过程并开始工作。新的系统拥有老系统的所有功能,并且还添加了许多内容,包括更好的用户界面。我收到的最后的信息表明团队书写且维护的 LOC 少于 5,000。这比 10X 的生产力增长要好,并且对于系统的所报告的缺陷比平均的少。

是的,Rails 不是玩具。

最后的想法

生成程序的想法不新颖。但我们最近几年已经大大地提高了该技术。Rails 是通过最少的工作,以清晰一致的方式生成特别类型的程序的非常有效的框架。您可以期盼更多像 Rails 这样的系统出现在不同的领域中。它刚好有良好的商业意义。事实上,在 Web 应用程序构建领域中还有其他的。有两个框架,类似于 Rails,用 PHP 写的。它们是 Symfony 和 CakePHP。 12 另一个有意思的是最近出现的 Project Zero,它是 IBM 中的温床项目。Project Zero 不是生成器,但提供使我想起 Rails 的惯例和结构。 13

如果您还没有投入 Web 应用程序的开发,那么我希望此专栏给您一些精神食粮,并且鼓励您花些时间获得一些快乐并使用 Rails。

注释

1 有许多在您的工作中帮助您的教程。参见本文最后的参考资料部分,了解其中的一些。依据教程,您将惊讶于构建 Web 应用程序会如此简单。

2 Rails 的第一个测试版发布于 2004 年 7 月。Rails 1.0 于 2005 年 12 月向世界发布。本文中的实例使用了版本 1.2.2。

3 http://www.basecamphq.com

4 参见 http://dev.rubyonrails.org,或的 Rails 存储库。

5 这在书籍的第 6 章中详细介绍。参见 Thomas 和 Hansson 等人的书籍,Agile Development with Rails,Pragmatic Bookshelf:2006 年。

6 Rails 支持大多数关系数据库管理系统。MySQL 是默认的,但变更为另一个数据库很平常。

7 您还将注意到,所有 Rails 生成文件使用的标准命名惯例。这令定位和确定每个文件的目的非常普通。

8 实际上,Active Record 是您可以用于任意应用程序的 Ruby Gems 之一。Rails 简单地采用了它,并在 Rails 应用程序中将其的使用标准化。

9http://www.martinfowler.com/eaaCatalog/activeRecord.html 查看 ActiveRecord 设计模式的描述

10 马萨诸塞州综合评价系统。参见 http://www.doe.mass.edu/mcas/testitems.html

11 参见 http://www.assistments.org

12 参见 http://www.symfony-project.com/http://cakephp.org/

13 参见 http://www.projectzero.org



参考资料

学习
  • 您可以参阅本文在 developerWorks 全球网站上的 英文原文

  • 您可以参阅 Rational Edge 电子月刊中文版 的其他文章。

  • 关于 Rails 的书籍有很多。我熟悉的有四个:
    • Agile Web Development with Rails,第 2 版。,Dave Thomas 和 David Heinemeier Hansson,The Pragmatic Programmers LLC,2006 年,ISBN 0977616630。
    • Build Your Own Ruby on Rails Web Applications,Patrick Lenz,SitePoint Pty. Ltd, 2007 年,ISBN 0975841955。
    • Rails for Java Developers,Stuart Halloway 和 Justin Gehtland, Pragmatic Programmers LLC,2007 年,ISBN 097761669。
    • Rails Cookbook,Rob Orsini,O'Reilly Media Inc., 2007 年,ISBN 0596527314。

  • 有许多在线资料可用。我推荐您从 Ruby on Rails 主页开始,http://www.rubyonrails.org/,使用那里的可用链接。


讨论
  • 参与论坛讨论

  • 现在开办了一个特别为 Rational Edge 的文章创办的 新论坛,现在您就可以分享您对本文或本期杂志或以前杂志中的其他文章的想法。阅读世界各地您的同行们所说的内容,生成您自己的讨论,或者加入正在进行的讨论。单击 这里 开始。

  • 全球 Rational 用户组社区


关于作者

Author photo

Gary Pollice 是麻省 Worcester 市 Worcester Polytechnic Institute 的一名实践教授。他教授软件工程、设计、测试以及其它计算机科学的课程,同时也指导学生项目。在进入学术界之前,他从事了 35 年多的软件开发,开发过各种软件,包括商业应用到编译器和工具等等。他在行业内的最后一份工作是在 IBM Rational 软件,他是有名的“RUP 倔老头”,同时也是最早的 Rational Suite 团队成员之一。 他是《小型团队软件开发:以 RUP 为中心的方法》(Software Development for Small Teams: A RUP-Centric Approach)一书的主要作者,该书由 Addison-Wesley 于 2004 年出版。他拥有数学专业文学学士学位,以及计算机科学理学硕士学位。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款