跨越边界: Streamlined,第 1 部分

来源:百度文库 编辑:神马文学网 时间:2024/04/29 23:47:16
用 Ajax、元编程和 Ruby on Rails 框架进行企业级搭建

文档选项

将此页作为电子邮件发送

拓展 Tomcat 应用

下载 IBM 开源 J2EE 应用服务器 WAS CE 新版本 V1.1
级别: 中级
Bruce Tate (bruce.tate@j2life.com), 总裁, J2Life, LLC
2006 年 10 月 30 日
Ruby on Rails 是一种基于 Ruby 编程语言的高效的 Web 开发环境。Streamlined 是基于 Ruby on Rails 的一个快速发展的开放源码框架。Streamlined 综合了 Ajax、元编程、代码生成以及 Ruby on Rails 的强大功能,把 Rails 的生产力带到了一个新层次。
我生平首次参加马拉松培训。马拉松培训最有趣的方面——实际上,也是惟一的方面——就是提高不断叠加所带来的影响。有时,我为了提高效率而进行专门为了改进身体条件而设计的长短跑。有时,在跑步过程中,我学习避免小的错误,避免重复多余的姿势(多余的姿势对单个步幅没有太大影响,但却会在整个 26.2 英里的跑步过程中浪费能量或伤害到我)。我每周都有提高,可每周之间的区别并不显著。但是一个训练计划周期过后,我会从最初只能跑 4 英里提高到能跑 26.2 英里。软件开发也与此类似。如果持续进行小的改进,消除多余的重复,您就会不断地累积提高,从而在今后的每个项目中都会做得更好。

在跨越边界 系列中,作者 Bruce Tate 提出这样一个观点:当今的 Java 程序员通过学习其他方法和语言会得到其他思路。自从 Java 明显成为所有开发项目的最佳选择以来,编程前景已经改变。其他的框架正在影响搭建 Java 框架的方式,从其他语言学到的概念可以影响您的 Java 编程。您编写的 Python(Ruby、Smalltalk……)代码可以改变您处理 Java 编码的方式。
本系列介绍了与 Java 开发有根本不同但是却直接适用的编程概念和技术。在某些情况下,需要集成这些技术以利用它。在其他情况下,则可以直接应用这些概念。比起其他语言和框架能够影响 Java 社区的开发人员、框架甚至基本方法这一概念,单独的工具不是那么重要。
在这篇包含两部分的文章中,我把重点放在 Ruby on Rails 搭建上,这是一个能够在早期开发阶段削减重复的 Rails 特性。第 1 部分介绍 Rails 搭建的限制和 Streamlined,Streamlined 是个代码生成器,它高效地应用了元编程技术来消除更高层次上的重复。第 2 部分将进一步深入 Streamlined 的元编程模型及其定制特性。
在整个跨越边界 系列中,我介绍了通过降低重复和提高效率实现反复改进的语言和框架:
具备诸如 duck typing 这类特性的编程语言,通过使用更少的类型定义、减少纯粹为了支持编译器所需要的代码数,能够提高灵活性和减少重复。
框架试图通过处理核心任务(例如持久性或事务)来提高效率和消除重复,这样就不必为每个新的应用程序编写代码。
Ruby on Rails 通过利用公共规范消除重复配置,允许框架推断您的意图,而不是强迫您配置应用程序特性(例如应用程序中特定的数据库表名称和列名称)。
就像所有高效的语言和框架必须做的那样,这些措施都把重点放在每个步骤上,或低级重复上。但是一旦搭建了一个有效的基础,就可以把目标放得更高。Rails 的搭建特性试图通过公共应用程序类型(数据库支持的 Web 应用程序)消除重复。

Rails 所做的削减数量惊人。重复配置、代码中重新阐述的规范,以及其他框架中的无效理念,在这个框架中都消失了。但是仍然存在大量的重复。对于所有的框架来说都是如此。请记住,日本汽车制造商不是靠造一辆车就威胁了奔驰和宝马公司的,而是通过不懈的改进。如果您为了搭建传统 Web 应用程序而在框架中寻找改进,那么仍然会找到大量可以削减的内容。
多数数据库支持的 Web 应用程序,几乎要为系统中每个主要的表都提供执行 CRUD 操作(创建、读取、更新和删除)的用户界面。 搭建这些用户界面应当自动进行,而不应当重复。 Rails 通过 搭建开始消除这种重复,搭建是一个特性,可以根据数据库表集合的内容构建默认的 CRUD 界面。使用 Rails,只用几个简单步骤,就可以从头开始构建一个搭建完整的应用程序。如果一直跟随 跨越边界 系列,那么以前就看过这些步骤。这次,我再把这些步骤简要介绍一下:
输入 rails trails 生成编排山地摩托车赛道的 Rails 应用程序。
用选中的数据库引擎创建叫作 trails_development 的数据库,并修改 trails/config/database.yml,以反映选中的配置。
切换到 trails 目录,,生成模型和控制器:输入 ruby script/generate model Trail (如果在 UNIX 上运行,可以省略 ruby) 生成叫作 Trail 的模型,输入 script/generate controller Trails 生成叫作 TrailsController 的控制器。
把文件 db/migrate/001_create_trail.rb 编辑成清单 1 那样:
class CreateTrails < ActiveRecord::Migration def self.up create_table :trails do |t| t.column :name, :string t.column :difficulty, :string t.column :description, :text end end def self.down drop_table :trails end end
把文件 app/controllers/trails_controller.rb 编辑成像清单 2 一样:
class TrailsController < ApplicationController scaffold :trail end
输入 rake migrate,运行迁移。
用命令 script/server 启动服务器,并把浏览器指到 localhost:3000/trails/list。
现在就已经得到了一个简单的能够工作的带有数据库支持的 Web 应用程序,可以进行基于 CRUD 的每个操作,如图 1 所示。可以看到主屏幕列出了每个项目和相关的图片,提供了 Ajax 窗口用来创建、读取、更新和删除项目。

到现在,只付出了很少努力,就到达了一个可以把应用程序开发带到更高档次的地步。Rails 演示人员总会展示搭建功能,因为它是如此之炫,而且对于调试和在匆忙之间为客户做演示,都极为有用。可以通过代码生成器生成搭建 —— 在这个示例中输入了 script/generate scaffold Trail Trails —— 或者在控制器中指定 scaffold 元编程标记。每种方式都有自己的用途。




回页首
搭建确实有一些明显限制:它不处理关系,也没有利用优秀的 Rails Web 服务或 Ajax 支持。为了说明这些限制,要创建带有模型、视图和控制器的 Location。Location 与 Trail 之间存在一对多关系。搭建并不能协助该关系的管理。
创建 location 的模型(script/generate model Location)和控制器(script/generate controller Location Locations)。就像对 TrailsController 所做的那样,把 scaffold :location 添加到 location_controller.rb。要把 Location 和 Trail 编织在一起,两者间需要多对一关系,所以把 belongs_to :location 添加到 Trail,把 has_many :trails 添加到 Location,如清单 3 所示:
class Trail < ActiveRecord::Base belongs_to :location end class Location < ActiveRecord::Base has_many :trails end
把 db/migrate/002_create_locations.rb 编辑成清单 4 那样:
class CreateLocations < ActiveRecord::Migration def self.up create_table :locations do |t| t.column :city, :string t.column :state, :string end add_column "trails", "location_id", :integer end def self.down drop_table :locations remove_column "trails", "location_id" end end
输入 rake migrate 运行迁移。(要查看关于迁移的更多内容,请参阅跨越边界: Rails 迁移。)
一下子就有了这么多设置。现在可以深吸一口气,总结以下到目前为止构建的内容:
有了一个针对赛道的数据库表和另一个针对地点的数据库表。 有了 Ruby 模型对象,对象之间还有 Rails 关系。 模型现在在赛道和地点之间有多对一关系。 有了处理模式中的变化的策略,也可以收回目前为止两个主要模式变化中的任何一个。 有了原始用户界面。
虽然可能想添加一些验证,但模型对象是适合生产应用的第一级 Rails 对象。许多 Rails 模型对象之所以简单,是因为属性都是用元编程动态添加的。为了演示现在的关系,通过控制台添加一些数据。输入 script/console 启动控制台,并输入清单 5 中的命令:
>> trail = Trail.new => #nil, "location_id"=>nil, "description"=>nil, "difficulty"=>nil}, @new_record=true> >> trail.name = "Hermosa Creek" => "Hermosa Creek" >> trail.difficulty = "easy" => "easy" >> trail.description = "22 miles of mostly downhill singletrack." => "22 miles of mostly downhill singletrack." >> trail.save => true >> location = Location.new => #nil, "state"=>nil}, @new_record=true> >> location.city = "Durango" => "Durango" >> location.state = "Co" => "Co" >> location.trails << trail => [#>, @attributes={"name"=>"Hermosa Creek", "id"=>1, "location_id"=>nil, "description"=>"22 miles of mostly downhill singletrack.", "difficulty"=>"easy"}, @new_record=false>] >> location.save => true >> hc = Trail.find 1 => #"Hermosa Creek", "location_id"=>"1", "id"=>"1", "description"=>"22 miles of mostly downhill singletrack.", "difficulty"=>"easy"}> >> hc.location => #"Durango", "id"=>"1", "state"=>"Co"}
清单 5 向数据库添加了一条赛道和一个地点,由从 trails 中的 location_id 列指向 locations 中的 id 列的外键管理。模型对象足够健壮,可以作为应用程序的构建基础。但是,视图就是另一回事了。
把浏览器指向 http://localhost:3000/trails/show/1,看到图 2 所示的屏幕:

在这里看不出 trail 和 location 之间的关系。还会注意到,搭建非常原始:它没有图片、没有 Ajax、没有公共标头或侧栏,也没有任何现代 Web 页面中常见的修饰。但重要的是通过 搭建,只花了几分钟就得到了一个相对复杂的应用程序。您可能并不指望这个简单特性能够生成健壮的代码,但是现在您可以把您的期望值抬高一点。
虽然搭建代表着对多数 Web 开发框架技术水平的显著提高,可它仍然有提高的余地,也应当如此。但是如果在此基础上构建,您会发现获益极多。这就像是从 13 英里开始马拉松训练,而不是从 4 英里开始。
搭建,像许多元编程技术一样,就是个运行时代码生成器。Rails 社区中的有些人认为搭建是有局限的,认为搭建还没有丰富到可以处理多数应用程序。其他人则认为搭建很好用,搭建的质量才是基本问题。这完全取决于应用程序的性质。如果正在构建一个重复的模式,那么会从构成搭建基础的元编程技术得到巨大收获。如果模板是充分可调整、充分丰富的,那么在框架中就能在更高层次上减少重复。现在开始介绍 Streamlined。




回页首
自从 Rails 出现以来,各种形式的和各种大小的 Rails 插件一直在提升所有应用程序开发的抽象程度。像登录生成器这样的组件允许生成安全性。其他插件使得在 Rails 中处理 Web 服务更容易。Streamlined 以其产品级质量的应用程序生成器超越了搭建。与使用搭建时一样,您可能需要扩展生成的代码,但初始的应用程序从它本身来说,其功能性令人惊讶。

Streamlined 由 Relevance LLC 创建,脱胎于进行自动培训(叫作 Code Site )的一组开源工具,而且每次 Relevance 构建商业 Rails 应用程序时,它都会得到改进。最终,此团队生成了通用的 Streamlined 框架,可以解决跨越众多项目的公共问题。
请下载初始 alpha 版本的 Streamlined .gem 文件(参阅参考资料)。切换到保存 .gem 的目录,并输入 gem install streamlined。所需要的所有内容都会自动安装。如果出现问题,可以通过 streamlined 的博客得到优秀的支持,也有商业支持可选。
现在是把 Streamlined 投入实践的时候了。首先,输入 script generate streamlined location trail,运行 Streamlined 生成器。当提示是否替换 locations 和 trails 控制器时,回答 y。
把浏览器指向 http://localhost:3000/locations/list 查看图 3 中的结果:

可以立即让 Streamlined 生成一个更完整的应用程序。把 Streamlined 列表与图 1 中的列表比较。区别是惊人的:
默认应用程序处理关系,单击其中一个 Edit 链接就可以看到。在下一节会看到更多关于关系的内容,在这篇文章的第 2 部分中甚至会更多。
应用程序更好地运用样式表,并生成更复杂的样式表。 Streamlined 运用各种技术,例如在表格周围使用
s,使得每个页面元素更容易进行样式处理。Streamlined 的 alpha 版本的样式处理有限,但是预期未来的版本会突破这个限制。
应用程序在左侧有默认的导航侧栏,在顶部有菜单和标头。这些菜单有更完整的默认行为,而且能够定制。
表格每一行都有代表编辑、显示或删除行的图片,应用程序还有额外的图片代表创建新条目、导出 CSV 以及把整个表导出为 XML。
这个页面看起来更像默认应用程序,而不太像不完整的搭建。这正是 Streamlined 的亮点。在深入之前,先对 Streamlined 的工作方式做个简单描述。
要使用 Streamlined,先要有一个可以工作的数据库模式、一个使用经典 Rails 工具和规范(在这篇文章中已经见到)的模型。然后,用 script/generate streamlined model1, model2, 等等命令生成 Streamlined 界面。Streamlined 观察 Rails 的命名规范,并在处于开发模式时频繁地重新装入应用程序对象,这样只要刷新浏览器,就可以看到最新的代码变化。
像 Rails 搭建一样,Streamlined 是个元编程框架,用元数据构建默认应用程序,构建的程序可以用各种方式定制。框架查询两个元数据源:活动记录模型和每个模型对象的定制元数据文件。默认情况下,Rails 从活动记录内捕获到足够的元数据,构建复杂的用户界面。活动记录查询数据库表,获得表中数据之外的信息,并且维护您所提供的其他信息,例如主键、关系、字段、字段类型、字段大小。Streamlined 利用所有这些信息来提供默认应用程序,但是要调整应用程序,框架还需要更多数据。Streamlined 提供了额外的元数据来源。
快速查看 trails/app 下的目录,可以看到 Rails 的常见目录:models、controllers、views 和 helpers。但是还有第五个目录可用:streamlined。就是在这里指定额外的元数据。streamlined 目录中四个文件快速列表说明了问题:
location.rb 和 trail.rb 包含同名模型的详细定制信息。
streamlined_relationships.rb 包含活动记录中指定的关系的更多信息,例如 Streamlined 要如何呈现关系。
streamlined_ui.rb 包含全局用户界面问题的配置信息,例如是否创建头、尾以及左侧导航栏。
Streamlined 立刻组合了代码生成(它生成可以修改的代码)和真正的元编程(它使用 Ruby 语言在运行时把代码动态地添加到应用程序)开始工作。Streamlined 生成日后可能要修改的静态内容和页面。例如,生成器直接把样式表和图片复制到您的项目。可以用真正的元编程或代码生成来创建视图,视图可能需要修改,也可能不需要修改。
通过操作这个默认应用程序,可以对它提供了多少特性有些感觉。左侧的导航侧栏拥有针对每个所指定模型的链接——针对本文的模型就是赛道和地点。单击链接,会进入每个模型的主页面。标头有管理域内对象的一套默认链接,有上下文敏感帮助,还有关于页面。
在进入表格数据区时,会看到更为复杂的功能。有充当记录过滤器的文本框。要查看它的工作方式,请单击 + 链接添加新赛道,并输入一些数据。然后,在主窗口输入 Her。将看到列表被调整成只有字段中包含指定文本的条目。也可以单击任意一个列名,根据这一列对列进行排序。
继续操作下去,肯定会注意到优秀的 Ajax 功能。在这里的 CRUD 设置中使用 Ajax 的最大好处是在一个主屏幕上就能提供管理表所需要的全部内容,只有很少的弹出框(用来编辑、显示和删除)。Ajax 支持更丰富的用户体验、更简洁的应用程序路径和更好的用户反馈。
最后看看关系管理。请单击左侧侧栏上的 Locations 链接。然后单击 + 图片,添加新地点(试着添加 Moab,Utah)。单击赛道下的 Edit,并选择应当属于这个地点的赛道。请注意 Streamlined 默认记录了属于每个地点的赛道的数量。这个默认行为已经非常丰富了,但是我在第 2 部分还要用更复杂的优化对它进行定制。




回页首
目前为止,最流行的 Java™ 框架都不生成 搭建,更不用说应用程序了。部分原因是在这个领域在根本上缺少驱动创新的竞争。Ruby on Rails 正在改变这种局面。而且,可以假设,在 Web 框架发展了八年之后,应当有人已经构建出了类似的东西。
应用程序生成器在 Java 环境中一直没有成功。它们有一个重要的问题:过多地依赖代码生成器,但在元模型上,却缺乏能够对代码生成进行补充的坚实的元编程框架。这类框架可以提供短期的生产力提升,但是不能在长时间内持续改进。生成的代码通常太脆弱和复杂。除非有足够的能力在每次代码生成之间定制代码,否则时间一长就会失去生产力。Streamlined 确实支持代码生成,但只支持应用程序中不变的那些部分,或者应用程序中简单的可变部分——例如视图和样式表,而这些内容开发人员可以容易地修改和维护。
有两个看起来想正确地混合代码生成和元数据的 Java 框架,它们是 RIFE 和 JMatter(请参阅参考资料)。我在这个系列中已经多次讨论过 RIFE,但是 JMatter 是新的。JMatter 框架拥有开源许可,也有商业报价。JMatter 基于 Hibernate 和 Swing,它允许根据元编程模型迅速地开发非常复杂的应用程序。Eitan Suez 这位 Java 圈中著名的发言人构建了 JMatter,以帮助快速地启动一项针对医疗实践的两层客户/服务器应用程序的 Java 开发。在将近两年的特化之后,JMatter 惊人地强壮,而且它的特性很容易与 Rails 和 Streamlined 对抗。如果 Jmatter 中的变化步伐能赶上 Ruby 社区的技术水平,那么它今后还会存在。




回页首
在这篇文章中,我介绍了 Rails 搭建、它的限制以及称作 Streamlined 的替代品。Streamlined 搭建得更完整,但到目前为止,它仍然还是搭建。在第 2 部分中,您将获得围绕 Streamlined 的元编程模型的更详细讨论,还将学习如何定制应用程序的关键部分。在这之前,您可以放飞思维、大量实践,继续跨越边界。
学习
您可以参阅本文在 developerWorks 全球站点上的英文原文 。
Java To Ruby: Things Your Manager Should Know (Pragmatic Bookshelf,2006):这是本文作者编著的一本书,讲述何时何处从 Java 编程转变到 Ruby on Rails 以及如何完成这种转变。
Beyond Java (O‘Reilly,2005):本文作者编写的一本书,讲述 Java 语言的提高和稳定发展,以及在某些方面能够挑战 Java 平台的技术。
“书评: 使用 Rails 进行敏捷 Web 开发 ”(Darren Torpey,developerWorks,2005 年 5 月):介绍了这样一本书,它可以加深读者对 Rails 及敏捷开发方式原理的理解。
Streamlined:访问 Streamlined 的 Web 站点和博客。
The Rails API:Rails 框架文档是从内到外学习搭建和让其工作的元编程技术的最佳途径。参阅 scaffolding.rb 类获得更多细节。
Programming Ruby (Dave Thomas et al., Pragmatic Bookshelf, 2005):一本关于 Ruby 编程的受欢迎的书。
Java 技术专区:这里有数百篇关于 Java 编程各个方面的文章。
获得产品和技术
Streamlined:下载 Streamlined 应用程序生成器并试用。Streamlined 正在快速发展,所以要下载初始的 alpha 版本。
RIFE:基于 Java 的元编程框架,它通过强大的元模型为基于 CRUD 的应用程序提供了非常好的搭建。
JMatter:下载新的 JMatter 框架,这是本文作者所看到的针对基于 Swing 和 Hibernate 的两层的应用程序的最佳框架。
Ruby on Rails:下载开放源码的 Ruby on Rails Web 框架。
Ruby:从该项目的 Web 站点获取 Ruby。
讨论
developerWorks bolgs:加入 developerWorks 社区。



Bruce Tate 居住在得克萨斯州的首府奥斯汀,他是一位父亲,同时也是山地车手和皮艇手。他是 3 本最畅销 Java 书籍的作者,其中包括荣获 Jolt 大奖的 Better, Faster, Lighter Java 一书,最近又出版了 Spring: A Developer‘s Notebook 一书。他在 IBM 工作了 13 年,现在是 J2Life, LLC 的创始人兼顾问。他潜心研究基于 Java 和 Ruby 的轻量级开发策略和架构。