2006 年 10 月 30 日 Ruby on Rails 是一種基于 Ruby 編程語(yǔ)言的高效的 Web 開(kāi)發(fā)環(huán)境。Streamlined 是基于 Ruby on Rails 的一個(gè)快速發(fā)展的開(kāi)放源碼框架。Streamlined 綜合了 Ajax、元編程、代碼生成以及 Ruby on Rails 的強(qiáng)大功能,把 Rails 的生產(chǎn)力帶到了一個(gè)新層次。 我生平首次參加馬拉松培訓(xùn)。馬拉松培訓(xùn)最有趣的方面——實(shí)際上,也是惟一的方面——就是提高不斷疊加所帶來(lái)的影響。有時(shí),我為了提高效率而進(jìn)行專(zhuān)門(mén)為了改進(jìn)身體條件而設(shè)計(jì)的長(zhǎng)短跑。有時(shí),在跑步過(guò)程中,我學(xué)習(xí)避免小的錯(cuò)誤,避免重復(fù)多余的姿勢(shì)(多余的姿勢(shì)對(duì)單個(gè)步幅沒(méi)有太大影響,但卻會(huì)在整個(gè) 26.2 英里的跑步過(guò)程中浪費(fèi)能量或傷害到我)。我每周都有提高,可每周之間的區(qū)別并不顯著。但是一個(gè)訓(xùn)練計(jì)劃周期過(guò)后,我會(huì)從最初只能跑 4 英里提高到能跑 26.2 英里。軟件開(kāi)發(fā)也與此類(lèi)似。如果持續(xù)進(jìn)行小的改進(jìn),消除多余的重復(fù),您就會(huì)不斷地累積提高,從而在今后的每個(gè)項(xiàng)目中都會(huì)做得更好。
在這篇包含兩部分的文章中,我把重點(diǎn)放在 Ruby on Rails 搭建上,這是一個(gè)能夠在早期開(kāi)發(fā)階段削減重復(fù)的 Rails 特性。第 1 部分介紹 Rails 搭建的限制和 Streamlined,Streamlined 是個(gè)代碼生成器,它高效地應(yīng)用了元編程技術(shù)來(lái)消除更高層次上的重復(fù)。第 2 部分將進(jìn)一步深入 Streamlined 的元編程模型及其定制特性。 在整個(gè) 跨越邊界 系列中,我介紹了通過(guò)降低重復(fù)和提高效率實(shí)現(xiàn)反復(fù)改進(jìn)的語(yǔ)言和框架:
就像所有高效的語(yǔ)言和框架必須做的那樣,這些措施都把重點(diǎn)放在每個(gè)步驟上,或低級(jí)重復(fù)上。但是一旦搭建了一個(gè)有效的基礎(chǔ),就可以把目標(biāo)放得更高。Rails 的搭建特性試圖通過(guò)公共應(yīng)用程序類(lèi)型(數(shù)據(jù)庫(kù)支持的 Web 應(yīng)用程序)消除重復(fù)。
多數(shù)數(shù)據(jù)庫(kù)支持的 Web 應(yīng)用程序,幾乎要為系統(tǒng)中每個(gè)主要的表都提供執(zhí)行 CRUD 操作(創(chuàng)建、讀取、更新和刪除)的用戶界面。 搭建這些用戶界面應(yīng)當(dāng)自動(dòng)進(jìn)行,而不應(yīng)當(dāng)重復(fù)。 Rails 通過(guò) 搭建開(kāi)始消除這種重復(fù),搭建是一個(gè)特性,可以根據(jù)數(shù)據(jù)庫(kù)表集合的內(nèi)容構(gòu)建默認(rèn)的 CRUD 界面。使用 Rails,只用幾個(gè)簡(jiǎn)單步驟,就可以從頭開(kāi)始構(gòu)建一個(gè)搭建完整的應(yīng)用程序。如果一直跟隨 跨越邊界 系列,那么以前就看過(guò)這些步驟。這次,我再把這些步驟簡(jiǎn)要介紹一下:
現(xiàn)在就已經(jīng)得到了一個(gè)簡(jiǎn)單的能夠工作的帶有數(shù)據(jù)庫(kù)支持的 Web 應(yīng)用程序,可以進(jìn)行基于 CRUD 的每個(gè)操作,如圖 1 所示??梢钥吹街髌聊涣谐隽嗣總€(gè)項(xiàng)目和相關(guān)的圖片,提供了 Ajax 窗口用來(lái)創(chuàng)建、讀取、更新和刪除項(xiàng)目。 圖 1. 簡(jiǎn)單的 Rails 應(yīng)用程序 ![]() 到現(xiàn)在,只付出了很少努力,就到達(dá)了一個(gè)可以把應(yīng)用程序開(kāi)發(fā)帶到更高檔次的地步。Rails 演示人員總會(huì)展示搭建功能,因?yàn)樗侨绱酥牛覍?duì)于調(diào)試和在匆忙之間為客戶做演示,都極為有用??梢酝ㄟ^(guò)代碼生成器生成搭建 —— 在這個(gè)示例中輸入了
搭建確實(shí)有一些明顯限制:它不處理關(guān)系,也沒(méi)有利用優(yōu)秀的 Rails Web 服務(wù)或 Ajax 支持。為了說(shuō)明這些限制,要?jiǎng)?chuàng)建帶有模型、視圖和控制器的 創(chuàng)建 location 的模型( 清單 3. trail.rb 和 location.rb 間的關(guān)系
把 db/migrate/002_create_locations.rb 編輯成清單 4 那樣: 清單 4. locations 表的遷移
輸入 一下子就有了這么多設(shè)置?,F(xiàn)在可以深吸一口氣,總結(jié)以下到目前為止構(gòu)建的內(nèi)容:
雖然可能想添加一些驗(yàn)證,但模型對(duì)象是適合生產(chǎn)應(yīng)用的第一級(jí) Rails 對(duì)象。許多 Rails 模型對(duì)象之所以簡(jiǎn)單,是因?yàn)閷傩远际怯迷幊虅?dòng)態(tài)添加的。為了演示現(xiàn)在的關(guān)系,通過(guò)控制臺(tái)添加一些數(shù)據(jù)。輸入 清單 5. 把數(shù)據(jù)添加到賽道和地點(diǎn)
清單 5 向數(shù)據(jù)庫(kù)添加了一條賽道和一個(gè)地點(diǎn),由從 把瀏覽器指向 http://localhost:3000/trails/show/1,看到圖 2 所示的屏幕: 圖 2. Rails 搭建沒(méi)有關(guān)系字段 ![]() 在這里看不出 trail 和 location 之間的關(guān)系。還會(huì)注意到,搭建非常原始:它沒(méi)有圖片、沒(méi)有 Ajax、沒(méi)有公共標(biāo)頭或側(cè)欄,也沒(méi)有任何現(xiàn)代 Web 頁(yè)面中常見(jiàn)的修飾。但重要的是通過(guò) 搭建,只花了幾分鐘就得到了一個(gè)相對(duì)復(fù)雜的應(yīng)用程序。您可能并不指望這個(gè)簡(jiǎn)單特性能夠生成健壯的代碼,但是現(xiàn)在您可以把您的期望值抬高一點(diǎn)。 雖然搭建代表著對(duì)多數(shù) Web 開(kāi)發(fā)框架技術(shù)水平的顯著提高,可它仍然有提高的余地,也應(yīng)當(dāng)如此。但是如果在此基礎(chǔ)上構(gòu)建,您會(huì)發(fā)現(xiàn)獲益極多。這就像是從 13 英里開(kāi)始馬拉松訓(xùn)練,而不是從 4 英里開(kāi)始。 搭建,像許多元編程技術(shù)一樣,就是個(gè)運(yùn)行時(shí)代碼生成器。Rails 社區(qū)中的有些人認(rèn)為搭建是有局限的,認(rèn)為搭建還沒(méi)有豐富到可以處理多數(shù)應(yīng)用程序。其他人則認(rèn)為搭建很好用,搭建的質(zhì)量才是基本問(wèn)題。這完全取決于應(yīng)用程序的性質(zhì)。如果正在構(gòu)建一個(gè)重復(fù)的模式,那么會(huì)從構(gòu)成搭建基礎(chǔ)的元編程技術(shù)得到巨大收獲。如果模板是充分可調(diào)整、充分豐富的,那么在框架中就能在更高層次上減少重復(fù)?,F(xiàn)在開(kāi)始介紹 Streamlined。
自從 Rails 出現(xiàn)以來(lái),各種形式的和各種大小的 Rails 插件一直在提升所有應(yīng)用程序開(kāi)發(fā)的抽象程度。像登錄生成器這樣的組件允許生成安全性。其他插件使得在 Rails 中處理 Web 服務(wù)更容易。Streamlined 以其產(chǎn)品級(jí)質(zhì)量的應(yīng)用程序生成器超越了搭建。與使用搭建時(shí)一樣,您可能需要擴(kuò)展生成的代碼,但初始的應(yīng)用程序從它本身來(lái)說(shuō),其功能性令人驚訝。
請(qǐng)下載初始 alpha 版本的 Streamlined .gem 文件(參閱 參考資料)。切換到保存 .gem 的目錄,并輸入 現(xiàn)在是把 Streamlined 投入實(shí)踐的時(shí)候了。首先,輸入 把瀏覽器指向 http://localhost:3000/locations/list 查看圖 3 中的結(jié)果: 圖 3. 默認(rèn)的 Streamlined 應(yīng)用程序 ![]() 可以立即讓 Streamlined 生成一個(gè)更完整的應(yīng)用程序。把 Streamlined 列表與 圖 1 中的列表比較。區(qū)別是驚人的:
這個(gè)頁(yè)面看起來(lái)更像默認(rèn)應(yīng)用程序,而不太像不完整的搭建。這正是 Streamlined 的亮點(diǎn)。在深入之前,先對(duì) Streamlined 的工作方式做個(gè)簡(jiǎn)單描述。 要使用 Streamlined,先要有一個(gè)可以工作的數(shù)據(jù)庫(kù)模式、一個(gè)使用經(jīng)典 Rails 工具和規(guī)范(在這篇文章中已經(jīng)見(jiàn)到)的模型。然后,用 像 Rails 搭建一樣,Streamlined 是個(gè)元編程框架,用元數(shù)據(jù)構(gòu)建默認(rèn)應(yīng)用程序,構(gòu)建的程序可以用各種方式定制??蚣懿樵?xún)兩個(gè)元數(shù)據(jù)源:活動(dòng)記錄模型和每個(gè)模型對(duì)象的定制元數(shù)據(jù)文件。默認(rèn)情況下,Rails 從活動(dòng)記錄內(nèi)捕獲到足夠的元數(shù)據(jù),構(gòu)建復(fù)雜的用戶界面。活動(dòng)記錄查詢(xún)數(shù)據(jù)庫(kù)表,獲得表中數(shù)據(jù)之外的信息,并且維護(hù)您所提供的其他信息,例如主鍵、關(guān)系、字段、字段類(lèi)型、字段大小。Streamlined 利用所有這些信息來(lái)提供默認(rèn)應(yīng)用程序,但是要調(diào)整應(yīng)用程序,框架還需要更多數(shù)據(jù)。Streamlined 提供了額外的元數(shù)據(jù)來(lái)源。 快速查看 trails/app 下的目錄,可以看到 Rails 的常見(jiàn)目錄:models、controllers、views 和 helpers。但是還有第五個(gè)目錄可用:streamlined。就是在這里指定額外的元數(shù)據(jù)。streamlined 目錄中四個(gè)文件快速列表說(shuō)明了問(wèn)題:
Streamlined 立刻組合了代碼生成(它生成可以修改的代碼)和真正的元編程(它使用 Ruby 語(yǔ)言在運(yùn)行時(shí)把代碼動(dòng)態(tài)地添加到應(yīng)用程序)開(kāi)始工作。Streamlined 生成日后可能要修改的靜態(tài)內(nèi)容和頁(yè)面。例如,生成器直接把樣式表和圖片復(fù)制到您的項(xiàng)目??梢杂谜嬲脑幊袒虼a生成來(lái)創(chuàng)建視圖,視圖可能需要修改,也可能不需要修改。 通過(guò)操作這個(gè)默認(rèn)應(yīng)用程序,可以對(duì)它提供了多少特性有些感覺(jué)。左側(cè)的導(dǎo)航側(cè)欄擁有針對(duì)每個(gè)所指定模型的鏈接——針對(duì)本文的模型就是賽道和地點(diǎn)。單擊鏈接,會(huì)進(jìn)入每個(gè)模型的主頁(yè)面。標(biāo)頭有管理域內(nèi)對(duì)象的一套默認(rèn)鏈接,有上下文敏感幫助,還有關(guān)于頁(yè)面。 在進(jìn)入表格數(shù)據(jù)區(qū)時(shí),會(huì)看到更為復(fù)雜的功能。有充當(dāng)記錄過(guò)濾器的文本框。要查看它的工作方式,請(qǐng)單擊 + 鏈接添加新賽道,并輸入一些數(shù)據(jù)。然后,在主窗口輸入 繼續(xù)操作下去,肯定會(huì)注意到優(yōu)秀的 Ajax 功能。在這里的 CRUD 設(shè)置中使用 Ajax 的最大好處是在一個(gè)主屏幕上就能提供管理表所需要的全部?jī)?nèi)容,只有很少的彈出框(用來(lái)編輯、顯示和刪除)。Ajax 支持更豐富的用戶體驗(yàn)、更簡(jiǎn)潔的應(yīng)用程序路徑和更好的用戶反饋。 最后看看關(guān)系管理。請(qǐng)單擊左側(cè)側(cè)欄上的 Locations 鏈接。然后單擊 + 圖片,添加新地點(diǎn)(試著添加 Moab,Utah)。單擊賽道下的 Edit,并選擇應(yīng)當(dāng)屬于這個(gè)地點(diǎn)的賽道。請(qǐng)注意 Streamlined 默認(rèn)記錄了屬于每個(gè)地點(diǎn)的賽道的數(shù)量。這個(gè)默認(rèn)行為已經(jīng)非常豐富了,但是我在第 2 部分還要用更復(fù)雜的優(yōu)化對(duì)它進(jìn)行定制。
目前為止,最流行的 Java? 框架都不生成 搭建,更不用說(shuō)應(yīng)用程序了。部分原因是在這個(gè)領(lǐng)域在根本上缺少驅(qū)動(dòng)創(chuàng)新的競(jìng)爭(zhēng)。Ruby on Rails 正在改變這種局面。而且,可以假設(shè),在 Web 框架發(fā)展了八年之后,應(yīng)當(dāng)有人已經(jīng)構(gòu)建出了類(lèi)似的東西。 應(yīng)用程序生成器在 Java 環(huán)境中一直沒(méi)有成功。它們有一個(gè)重要的問(wèn)題:過(guò)多地依賴(lài)代碼生成器,但在元模型上,卻缺乏能夠?qū)Υa生成進(jìn)行補(bǔ)充的堅(jiān)實(shí)的元編程框架。這類(lèi)框架可以提供短期的生產(chǎn)力提升,但是不能在長(zhǎng)時(shí)間內(nèi)持續(xù)改進(jìn)。生成的代碼通常太脆弱和復(fù)雜。除非有足夠的能力在每次代碼生成之間定制代碼,否則時(shí)間一長(zhǎng)就會(huì)失去生產(chǎn)力。Streamlined 確實(shí)支持代碼生成,但只支持應(yīng)用程序中不變的那些部分,或者應(yīng)用程序中簡(jiǎn)單的可變部分——例如視圖和樣式表,而這些內(nèi)容開(kāi)發(fā)人員可以容易地修改和維護(hù)。 有兩個(gè)看起來(lái)想正確地混合代碼生成和元數(shù)據(jù)的 Java 框架,它們是 RIFE 和 JMatter(請(qǐng)參閱 參考資料)。我在這個(gè)系列中已經(jīng)多次討論過(guò) RIFE,但是 JMatter 是新的。JMatter 框架擁有開(kāi)源許可,也有商業(yè)報(bào)價(jià)。JMatter 基于 Hibernate 和 Swing,它允許根據(jù)元編程模型迅速地開(kāi)發(fā)非常復(fù)雜的應(yīng)用程序。Eitan Suez 這位 Java 圈中著名的發(fā)言人構(gòu)建了 JMatter,以幫助快速地啟動(dòng)一項(xiàng)針對(duì)醫(yī)療實(shí)踐的兩層客戶/服務(wù)器應(yīng)用程序的 Java 開(kāi)發(fā)。在將近兩年的特化之后,JMatter 驚人地強(qiáng)壯,而且它的特性很容易與 Rails 和 Streamlined 對(duì)抗。如果 Jmatter 中的變化步伐能趕上 Ruby 社區(qū)的技術(shù)水平,那么它今后還會(huì)存在。
在這篇文章中,我介紹了 Rails 搭建、它的限制以及稱(chēng)作 Streamlined 的替代品。Streamlined 搭建得更完整,但到目前為止,它仍然還是搭建。在第 2 部分中,您將獲得圍繞 Streamlined 的元編程模型的更詳細(xì)討論,還將學(xué)習(xí)如何定制應(yīng)用程序的關(guān)鍵部分。在這之前,您可以放飛思維、大量實(shí)踐,繼續(xù)跨越邊界。 學(xué)習(xí)
獲得產(chǎn)品和技術(shù)
討論
|
聯(lián)系客服