Web開發(fā)人員的利器:Ruby on Rails

          Web開發(fā)人員的利器:Ruby on Rails

          ?????????????????????????????????????????????????????????????????????? 作者:Jonathan Palley
          工具發(fā)展簡(jiǎn)史

            人類的發(fā)展就是工具的發(fā)展。從石器到木棒和矛,再到火器,我們學(xué)會(huì)了如何更有效地捕獵。從觀看星像到指南針,再到海洋精密計(jì)時(shí)儀(marine chronometers)和全球定位系統(tǒng)(GPS),我們發(fā)現(xiàn)了如何更好地進(jìn)行導(dǎo)航。從書信到電報(bào),再到電話和互聯(lián)網(wǎng),我們將人類通訊的方式進(jìn)行了革命。人類能夠進(jìn)行創(chuàng)新。我們能夠發(fā)現(xiàn)解決問題的更有效的方法。我們能夠創(chuàng)造更好的工具——這些工具對(duì)于我們所要解決的問題來說,顯得更具有針對(duì)性和專門化,因而更為高效。

          ???  程序員也一樣。優(yōu)秀的程序員總是在尋找解決問題的更好的方法,這些方法更易于理解、需要更少的重復(fù)性工作和更少的代碼,并且也更易于測(cè)試。David Heinemeier Hansson 就是這樣一個(gè)優(yōu)秀的程序員。

          ???  兩年多之前,David寫了一個(gè)叫做 Basecamp 的Web應(yīng)用程序。當(dāng)他考察一些現(xiàn)有的工具時(shí),他發(fā)現(xiàn)沒有任何一種語言和框架是被設(shè)計(jì)成能夠以一種他認(rèn)為是完全有可能的最簡(jiǎn)潔、需要最少的重復(fù)性工作以及是最容易測(cè)試的方式來開發(fā)Web應(yīng)用。他在Ruby語言中看到了他心目中的理想工具所需的靈活性和能力。就這樣,Web 應(yīng)用開發(fā)框架 Ruby on Rails 從Basecamp 和 Ruby 中誕生了。

            Rails是被設(shè)計(jì)用于開發(fā)Web 應(yīng)用的。你不應(yīng)當(dāng)使用Rails來開發(fā)數(shù)據(jù)挖掘算法、企業(yè)財(cái)務(wù)系統(tǒng)或桌面應(yīng)用。你應(yīng)當(dāng)使用Rails來開發(fā)Web應(yīng)用。同時(shí),Rails將會(huì)促使你以一種更快和更可靠的方式來開發(fā),而在這之前你會(huì)認(rèn)為這種方式是不可能的。

          RoR確實(shí)具有可伸縮性
            如果你對(duì)“可伸縮性”的定義是要求達(dá)到Google搜索引擎或是Yahoo的首頁那樣的數(shù)量級(jí),那么你不再需要繼續(xù)閱讀本文了。實(shí)際上,沒有任何一種現(xiàn)有的商業(yè)解決方案能夠適用于那樣規(guī)模巨大的網(wǎng)站。然而,如果你正在開發(fā)一個(gè)Web應(yīng)用,并且你在還沒有10萬個(gè)用戶的情況下就開始考慮如何處理1億個(gè)用戶的情況,那么你應(yīng)當(dāng)重新考慮開發(fā)時(shí)的優(yōu)先級(jí)。Web開發(fā)人員首先需要關(guān)注的是開發(fā)出一個(gè)用戶喜歡和愿意使用并且具有較好的體系結(jié)構(gòu)的Web應(yīng)用。如果你能很好地做到這一點(diǎn),你才會(huì)有時(shí)間和金錢來有效地應(yīng)對(duì)你的第1億個(gè)用戶。Rails鼓勵(lì)你在為一個(gè)Web應(yīng)用設(shè)計(jì)體系結(jié)構(gòu)時(shí)采取一些最佳的實(shí)踐方法,從而使得當(dāng)需求出現(xiàn)時(shí),你能夠?qū)?yīng)用進(jìn)行優(yōu)化和提升性能。

            需要表明的是:Ruby on Rails是具有可伸縮性的。它被成功地運(yùn)用在了真實(shí)世界中的具有很大訪問量的應(yīng)用中。這不是猜想或假定,這是事實(shí)。目前,Ruby on Rails正在很多高端的Web應(yīng)用中服務(wù)著每天數(shù)以百萬計(jì)的請(qǐng)求。這些使用了Ruby on Rails的Web應(yīng)用包括,Basecamp(37signal.com)、Odeo(odeo.com)、 43things(43things.com)、insiderpages(insiderpages.com)、zvents(zvents.com) 以及A List Apart(alistapart.com)。這些Web應(yīng)用中的每一個(gè)每天都在響應(yīng)著數(shù)以百萬計(jì)的頁面請(qǐng)求,同時(shí),數(shù)千萬的風(fēng)險(xiǎn)投資基金在支持著這些公司。一個(gè)使用了Rails的叫做CashNetUSA的公司剛剛以三千五百萬美元的價(jià)格被收購。

            在美國,同其他編程語言或技術(shù)相比,對(duì)于Ruby 和 Rails的職位需求的增長(zhǎng)最大。除此之外,有關(guān)Ruby 以及Ruby on Rails的圖書銷售超過了像Perl這樣流行的語言。這并不表示某種潮流或表明Ruby on Rails是一種“玩具語言”——因?yàn)楹芏嗾鎸?shí)的公司正在將Rails集成到他們現(xiàn)有的工作流程中。Google、Amazon、IBM 以及美國聯(lián)邦政府的許多部門都在內(nèi)部使用Rails。頂尖的NASA科學(xué)家也在同時(shí)使用Python和Ruby。

            對(duì)于Rails的最大誤解或許就是,它被認(rèn)為不能用于真正的應(yīng)用中。正如上文所說:一些流量很大的網(wǎng)站正在成功地使用Rails,它們甚至在Rails 1.0 發(fā)布之前就開始使用了。我無法在這篇文章中展示出詳細(xì)的流量數(shù)據(jù)。然而,所有的這些網(wǎng)站每天都有數(shù)以百萬計(jì)的頁面訪問量,它們都需要處理性能提升的問題,并維持一個(gè)良好的網(wǎng)站正常運(yùn)行率。下面我將對(duì)這些應(yīng)用做一個(gè)簡(jiǎn)單介紹:

            Basecamp:Ruby on Rails就是從Basecamp的代碼中提煉出來的。Basecamp也是一個(gè)在線項(xiàng)目管理系統(tǒng)。就像ruby on Rails一樣,它非常簡(jiǎn)單,然而卻很強(qiáng)大。它的功能包括:創(chuàng)建項(xiàng)目里程碑和待辦事項(xiàng)列表、發(fā)送消息、上傳文件、管理項(xiàng)目人員等等。Bascamp 是由一個(gè)名為 37signals的公司創(chuàng)建的。在創(chuàng)建Basecamp之后,他們還開發(fā)了很多其它的在線協(xié)同工作的應(yīng)用,所有這些都使用了Ruby on Rails。我所在的公司,即Idapted,在內(nèi)部使用basecamp來管理各種各樣的工作流程和項(xiàng)目。通過快速的網(wǎng)上搜索,你將能看到很多很多公司都在依賴于Basecamp來完成工作。

          ??Odeo:Odeo是一個(gè)語音博客/播客(podcasting)的Web應(yīng)用。它使得人們可以在網(wǎng)站上創(chuàng)建和錄制播客內(nèi)容和其他語音信息,建立RSS種子,加入注釋,等等。它實(shí)際上就是一個(gè)帶有音頻信息的博客應(yīng)用。該應(yīng)用在Ruby on Rails還沒有到達(dá)1.0時(shí)就使用了它來開發(fā)。

          ??InsiderPage :InsiderPages是一個(gè)社會(huì)黃頁應(yīng)用。它使得人們可以對(duì)他們所在區(qū)域中的各種企業(yè)發(fā)表意見和評(píng)級(jí)。該應(yīng)用最初是用Java寫的,并使用了通常的Struts/Hibernate等框架。然而他們發(fā)現(xiàn)Java代碼缺乏靈活性和適應(yīng)性,無法滿足他們的應(yīng)用。他們希望能夠快速對(duì)用戶的反饋和功能需求作出反應(yīng),并能夠容易地發(fā)布小版本和進(jìn)行更新。他們把全部的應(yīng)用轉(zhuǎn)換成了基于Ruby on Rails,并發(fā)現(xiàn)開發(fā)過程得到極大的改進(jìn)。

            盡管InsiderPages不允許我公布有關(guān)他們從Java轉(zhuǎn)換到Rails的具體數(shù)字,不過已經(jīng)有一些已發(fā)表的我認(rèn)為很能說明問題的估計(jì)數(shù)字。完整的內(nèi)容可以從以下的地址得到: http://article.gmane.org/gmane.comp.lang.ruby.rails/24863 。 這篇貼子描述的是,參與了某個(gè)使用Java/Hibernate/JSP/Struts/Ajax/Unit test技術(shù)來開發(fā)企業(yè)級(jí)項(xiàng)目的開發(fā)人員發(fā)現(xiàn),當(dāng)從Java轉(zhuǎn)換到Rails后,代碼行數(shù)減少到原來的25分之一。這里是從該貼子中摘錄的一些統(tǒng)計(jì)數(shù)據(jù):


          Java version:

          10361 lines of Java code
          1143? lines of JSP
          8082? lines of XML
          1267? lines of build configuration
          -----------------------------------------------------------
          20853 TOTAL lines of stuff

          Rails version:

          494?? lines of code (386 "LOC" per rake stats)
          254?? lines of RHTML
          75??? lines of configuration (includes comments in routes.rb)
          0???? lines of build configuration
          -----------------------------------------------------------
          823?? TOTAL lines of stuff

            盡管有人肯定會(huì)爭(zhēng)論說,這個(gè)項(xiàng)目采用Java也可以有更加有效的方法,不過采用Rails的真正好處并不在于此。Ruby on Rails的美妙之處并不是它能使你寫更少的代碼,而是能使你寫出能夠反應(yīng)出你的意圖的代碼。Rails提供了一個(gè)開發(fā)Web應(yīng)用的框架,它使你寫出的代碼能夠反應(yīng)出該應(yīng)用的情況。使用Rails 之后,開發(fā)人員不再需要關(guān)心那些配置信息,也不必再去把那些對(duì)于該應(yīng)用的功能沒有直接貢獻(xiàn)的模塊和代碼捆綁在一起。Ruby on Rails使得Web開發(fā)人員可以寫出只做一件事情的代碼:這就是,描述他們正在開發(fā)的應(yīng)用情況。

          Rails 的優(yōu)勢(shì)
            Rails 能夠節(jié)省時(shí)間并且還能構(gòu)架和開發(fā)更好的 Web應(yīng)用, Rails之所以有這些好處,是因?yàn)樗?Web 開發(fā)者只專注于與應(yīng)用程序的功能直接相關(guān)的代碼。這篇文章的其他部分將會(huì)探索Rails 是如何做到這點(diǎn)并成為了廣受贊譽(yù)的工具的。由于這篇文章致力于比較不同的Web 開發(fā)框架,Rails 是否是適合你的工具?我相信最好的方式是將決策權(quán)交給你,在這里我們只進(jìn)行展示和討論。

            但是,為了讓下面的種種討論在我們規(guī)定的范圍之內(nèi),我將先討論一下 Rails和 PHP/ASP.net/Java相比在概念上的優(yōu)勢(shì)。

            PHP 最初被設(shè)計(jì)來向在 Web頁面里嵌入小腳本,而不是完成 Web 應(yīng)用。面向?qū)ο缶幊痰母拍睿簩?duì)象、類、繼承等等是在后期引入的。雖然PHP5 在面向?qū)ο蠓矫孀龀隽酥卮蟮母倪M(jìn),它依然無法真正體現(xiàn)面向?qū)ο笳Z言的優(yōu)勢(shì)。Ruby 則是純面向?qū)ο笳Z言而Rails 充分利用了這一點(diǎn)。Ruby 中的一切都是類并且不存在簡(jiǎn)單類型。正如我們之后所要演示的,Rails 通過這些面向?qū)ο筇匦源蛟炝思僊VC(Model-View-Controller )框架以及強(qiáng)大靈活的 OR映射。Rails更進(jìn)一步地通過繼承和混入 (mixin) 使得整個(gè)框架極易被擴(kuò)展。通過有效率的語法,各種插件以及特定領(lǐng)域語言(Domain Specific Language))可以輕松的在框架之上進(jìn)行種種定制。Ruby 的靈活性使得Rails 成為Web 開發(fā)者的最愛。因此你不能簡(jiǎn)單地界定Ruby 是一種開發(fā)語言而PHP 是一個(gè)框架。

            ASP.net 被局限在一種平臺(tái),一種 Web服務(wù)器,如果你想讓它更具效率, SQL Server 則是持久層的唯一選擇。Rails 卻幾乎可以運(yùn)行在任何平臺(tái)并與任意的數(shù)據(jù)庫交互。與擁有簡(jiǎn)單強(qiáng)大的ActiveRecord 作為ORM 的Rails 相比,ASP.net 的開發(fā)者卻時(shí)常迷失在DataAdapters、Connection Objects、Command Objects、DataSets……的世界里。在 MVC 框架是否簡(jiǎn)潔,是否強(qiáng)大的方面,ASP.net無法與 Rails相提并論,更不要說Rails 所能給予我們的靈活性以及強(qiáng)大能量。

            Ruby 是一種極度靈活的動(dòng)態(tài)語言。你可以通過class_evals、混合(mixins )、動(dòng)態(tài)類型(duck typing) 動(dòng)態(tài)擴(kuò)展對(duì)象。Java與 Ruby 相比,最大的問題在語言本身的靈活性上。這是為什么Java web開發(fā)是基于規(guī)范和定義的其中一個(gè)原因。在基于Structs/Hibernate/ 等框架的Java web開發(fā)中,不使用 XML 文件或者其他冗余的定義代碼是幾乎不可能的。通過對(duì)一些應(yīng)用從Java 遷移Rails的統(tǒng)計(jì),我們可以看出,Ruby 語言的靈活性使得Web應(yīng)用被開發(fā)的更加迅速,而且與Java 相比代碼的數(shù)量大大減少了。
          ?
          RoR無法掩蓋的特性
            現(xiàn)在是討論那些真正使得Rails成為Web 開發(fā)語言大贏家的特性的時(shí)候了。這篇文章并非面面俱到,它不是一篇指南性質(zhì)的文章。我略去了那些在開發(fā)Rails應(yīng)用中我認(rèn)為不能說明Rails 更加強(qiáng)大的部分。后面的內(nèi)容更多的是讓你對(duì)Rails 的世界有所了解。
          ?
          約定勝于配置
            Rails是一個(gè)真正的MVC(Model-View-Controller))框架。它清楚地將你的模型(數(shù)據(jù)庫)的代碼與你的控制器(應(yīng)用邏輯))從視圖代碼中清楚地分離出來。一個(gè)Rails開發(fā)者很少或者可能從未思考過“這段代碼應(yīng)該放在哪一層?”,在Rails 的世界中,適合你那段代碼生長(zhǎng)的環(huán)境有且僅有一處。

            事實(shí)上,與配置相比,Rails 更傾向于約定。這意味著如果你遵守Rails的約定,你將很少,也許永遠(yuǎn)不會(huì)與配置文件打交道。更重要的是,你永遠(yuǎn)不需要把時(shí)間浪費(fèi)在搞明白如何配置你的應(yīng)用上,你所有的精力都花在如何正確地實(shí)現(xiàn)應(yīng)用。當(dāng)然,所有的東西也是可以配置的。如果你開始一個(gè)新的應(yīng)用,似乎沒有什么原因使我們拒絕遵守 Rails的約定。

            例如你的models 應(yīng)該被放在app/models/ 目錄, controllers 被放在 the app/controllers / 目錄而views 被放在 app/views/controller_name/ 目錄。 一旦你把這些文件放在正確的位置,Rails將自動(dòng)發(fā)現(xiàn)它們并把它們加入到應(yīng)用中。Url 映射是自動(dòng)完成的。訪問 http://yoursite/admin/list 意味著應(yīng)用中有命名為 admin的控制器與命名為 list的視圖與之對(duì)應(yīng)。

            約定優(yōu)于配置的觀念 對(duì)Rails的影響不僅僅如此。不但你無需考慮“這個(gè)文件放在哪兒?”,你也無須考慮“我該如何命名這個(gè)文件”,命名的原則是盡量自然并且使得大多數(shù)的代碼可讀性更好。模型( Model)的名字應(yīng)該為單數(shù),這樣在模型(Model)是以單數(shù)還是復(fù)數(shù)形式被引用取決于它在什么時(shí)候更有意義。例如假設(shè)在系統(tǒng)中, Person持有多個(gè)Message ,你大可以寫出如下代碼。
          ?
          Person.find(person_id).messages
          或者
          Message.find(message_id)

            注意,message是如何以單數(shù)形式被引用的,而與 Person 關(guān)聯(lián)的多個(gè)message 則是復(fù)數(shù)形式。這樣更有意義。由于我們還將討論框架的其他元素,你將發(fā)現(xiàn)約定勝于配置的觀念在Rails中是如何的根深蒂固。

          Ruby的最佳實(shí)踐——ActiveRecord
            上面的例子引入了Rails 最有趣的部分之一:ActiveRecord,ActiveRecord 是ORM層,它是Ruby 語言靈活性的最佳實(shí)踐。為了沿用上面的例子,我們對(duì)數(shù)據(jù)庫結(jié)構(gòu)進(jìn)行如下設(shè)計(jì):
          create table users (
          ?id? int auto_increment;
          ?name varchar(100);
          ?email varchar(100);
          ?city varchar(100);
          primary key (id)
          )
          ?
          create table messages (
          ?id int;
          ?user_id int;
          ?message varchar(100);
          ?created_on timestamp;
          primary key (id)
          )
          ?
          然后我們運(yùn)行rails腳本:
          script/generate model user message.

          Rails生成了下列文件并把它們放入了 app/models目錄:
          ?
          user.rb
          class User < ActiveRecord::Base
          end
          ?
          message.rb
          class Message < ActiveRecord::Base
          end
          ?
          注意表是以復(fù)數(shù)形式存在(這樣SQL語句如 SELECT * FROM USERS就更有意義),而對(duì)應(yīng)的類則是單數(shù)。
          沒有使用任何配置我們已經(jīng)自動(dòng)得到了最基本的創(chuàng)建,查詢,更新以及刪除的方法(Message.find, Message.create, Message.delete, Message.update_attributes ),而且這些方法都是真正可以工作的,我們可以在控制器中立刻使用這些方法。如果我們想查找一個(gè)名叫"kevin"的用戶。我們可以寫出如下代碼:
          ?
          User.find(:condition => "name = 'kevin'").
          ?
          User.find將自動(dòng)生成正確的 SQL,但是,這段代碼讀并不易懂。通過使用ruby語言的動(dòng)態(tài)部分, ActiveRecord同樣允許我們寫出這樣的代碼:
          ?
          User.find_by_name("kevin")
          或者
          User.find_by_name_and_email("kevin", "
          kevin@example.com ").??
          ?
          同樣,如果我們想查出從北京來的用戶,我們大可以寫出這樣的代碼:
          ?
          User.find_all_by_city("Beijing").
          僅僅簡(jiǎn)單的查找或者持久化數(shù)據(jù),使我們?cè)趲追昼娭缶团d致索然了。數(shù)據(jù)庫和Web 應(yīng)用之所以值得關(guān)注,是它使得數(shù)據(jù)之間相互關(guān)聯(lián)。我們對(duì)ActiveRecord 模型進(jìn)行相應(yīng)的修改:
          ?
          user.rb
          class User < ActiveRecord::Base
          ??has_many :messages
          end
          ?
          message.rb
          class User < ActiveRecord::Base
          ?belongs_to :user
          end
          ?
            我們現(xiàn)在得到了User 和Messages 的一對(duì)多的 (one-to-many) 關(guān)系,按照rails的約定,messages 表中應(yīng)該存在user_id字段,has_many和belongs_to做了什么?在這兩個(gè)簡(jiǎn)單方法背后,它們向我們的 model類中添加大量的新的實(shí)例方法。例如,不進(jìn)行任何額外的工作,在控制器中,我們可以這樣做:
          ?
          @user = User.find_by_name("kevin")
          @user.create_message(:text => "hello world").
          ?
          這段代碼向Kevin這個(gè)用戶添加了一條新的message 記錄。而且,Rails 自動(dòng)將記錄創(chuàng)建的時(shí)間戳持久化到created_on字段。我們可以通過如下的代碼得到Kevin 相關(guān)的message。
          ?
          @kevins_messages = @user.messages


          AJAX中的視圖
            Rails中的視圖,其實(shí)是一個(gè)經(jīng)由erb(embedded ruby,嵌入式Ruby)處理過的html文件,借此可將Ruby功能輕松嵌入html。Rails框架提供大量用于生成視圖文件的工具函數(shù)。視圖文件在控制器里與動(dòng)作(或方法)關(guān)聯(lián)。下面,我們就創(chuàng)建一個(gè)視圖,用以顯示Kevin的消息:

          <for message in @kevins_messages>
          <div class=”message”>
          <strong>Sent:</strong><%= message.created_on %>
          <strong>Body:</strong><%= message.body %>
          </div>
          <% end %>

            看,Ruby代碼被完美嵌入html。我們?cè)俳o動(dòng)作增加一個(gè)創(chuàng)建新消息的鏈接。為此,我們需要使用Rails中的一個(gè)工具函數(shù):

          <div id=”new_message”>
          <%= link_to 'Create New Message', :url => {:action => 'create'} %>
          </div>

            執(zhí)行時(shí),程序會(huì)調(diào)用控制器中的一個(gè)名為“create”動(dòng)作(或方法)。因此在我們的視圖文件目錄中,將會(huì)自動(dòng)產(chǎn)生名為create.rhtml的文件。這個(gè)文件的RHTML視圖代碼可以生成一個(gè)html表單,以此可以創(chuàng)建新的消息。
          為什么一定要在新頁面上創(chuàng)建這個(gè)表單呢?當(dāng)創(chuàng)建新消息時(shí),讓表單出現(xiàn)在當(dāng)前頁面,這樣我能同時(shí)看到舊的消息,不是更好嗎?如果使用AJAX,這是可以實(shí)現(xiàn)的。Rails中大量的工具函數(shù)就能讓我們不使用JavaScript也可以編寫AJAX應(yīng)用,太美妙了。這些東西在Ruby里都是現(xiàn)成的。使用AJAX創(chuàng)建我們的鏈接,我們只需要做如下簡(jiǎn)單修改:

          <%= link_to_remote 'Create New Message', “new_message”, :url=>{action=>'create} %>

            Rails利用Prototype或Scriptaculous框架里的JavaScript庫,在頁面里生成了相應(yīng)的JavaScript程序。“Create New Message”鏈接被點(diǎn)擊時(shí),對(duì)服務(wù)器的AJAX請(qǐng)求被生成,請(qǐng)求的響應(yīng)也在“new_message”區(qū)里被創(chuàng)建。
          Rails 1.1甚至以RJS的方式,實(shí)現(xiàn)了對(duì)JavaScriot更高級(jí)的支持。RJS讓不使用JavaScript就能編寫JavaScript功能成為可能——你寫的Ruby和Rails代碼將在適當(dāng)時(shí)候被自動(dòng)轉(zhuǎn)化為JavaScript。用這種手段搭建高交互性的站點(diǎn),我們就可以心無旁騖,專注于MVC的設(shè)計(jì)模式。
            RJS文件有點(diǎn)像RHTML。但它不會(huì)被轉(zhuǎn)化為HTML,在一個(gè)AJAX請(qǐng)求里,RJS是以JavaScript方式執(zhí)行的。舉個(gè)例子,我們希望上面提到的“Create New Message”AJAX鏈接不僅顯示表單,而且要讓其呈高亮態(tài),并出現(xiàn)一個(gè)導(dǎo)航警告,最后調(diào)用JavaScript函數(shù)。好,我們就用RJS文件create.rjs替代create.rhtml,其格式與如下相仿:

          page.replace_html 'new_message', :partial => 'new_message_form'
          page.visual_effect :highlight, 'new_message'
          page.alert('Directions go here')
          page.<< “js_func_to_call”

          代碼“:partial => 'new_message_form”說明我們希望生成另一個(gè)名為“_new_message_form.rhtml”的rhtml文件。這里的“partial”實(shí)際上和先前包含表單的create.rhtml完全相同。

          Ruby語言——DSL
            聰明的讀者可能已經(jīng)知道,Rails的威力大多來源于Ruby語言本身的靈活性。我不想過多討論Ruby的重要性,這里要重點(diǎn)介紹的是一個(gè)以此為基礎(chǔ)且令人驚嘆的衍生品。Ruby允許創(chuàng)建各種DSL(Domain Specific Language)。這些袖珍型語言為特定領(lǐng)域而設(shè)計(jì),可以使用Ruby直接創(chuàng)建。RJS文件是DSL的一個(gè)例子。例中,被創(chuàng)建的DSL將JavaScript功能加入了站點(diǎn)。?
            在我公司開發(fā)的一個(gè)應(yīng)用里,DSLs發(fā)揮了巨大作用。比如,我們應(yīng)用里很大一個(gè)部分是處理VoIP(譯者注:Voice over IP,網(wǎng)絡(luò)語音或網(wǎng)絡(luò)電話)和Web接口的交互。因此,我們的應(yīng)用需要控制并與VoIP服務(wù)器交互。VoIP服務(wù)器使用了一個(gè)叫做Asterisk的開源平臺(tái)。Asterisk提供一個(gè)叫做AGI的功能集,允許編程使用TCP鏈接控制服務(wù)器。而AGI API凌亂不堪,因此,我們開發(fā)了一個(gè)DSL,以此封裝AGI的功能,允許我們用Rails開發(fā)清晰而簡(jiǎn)潔開發(fā)語音接口。用DSL抽象封裝了混亂的AGI代碼,我們就能以清晰的思路,直接編寫實(shí)際的應(yīng)用功能代碼。
            這里有一個(gè)我們開發(fā)的基于銀行應(yīng)用的語音功能DSL例子。首先,它創(chuàng)建一個(gè)輸入提示表單,應(yīng)用以此通過電話收集各項(xiàng)細(xì)節(jié)信息。其結(jié)構(gòu)和HTML表單類似。然后將所有收集到的信息送入Rails控制器里的action,action完成信息的處理并將結(jié)果寫入數(shù)據(jù)庫。

          ?asterisk.form :action=>'create' do |form|
          ? form.numeric_input 'bank-deposit-or-withdrawl', 'type', 1000
          ?  form.numeric_input 'bank-enter-line-item-amount', 'line_item[amount]'
          ?  form.record_input session.id.to_s, 'line_item[description]'
          ? end

            用DSL按照Ruby語法習(xí)慣編寫代碼,asterisk表單的結(jié)構(gòu)和表現(xiàn)方式就完全掌握在我們自己手里了。DSL的厲害就在于它可以把與AGI交互的功能以完全不同的方式而又非常條理化地抽象出來。

          高度集成的測(cè)試
            使用Rails快速完成Web應(yīng)用開發(fā),但最后就得為測(cè)試煞費(fèi)苦心了吧?事實(shí)并非如此,測(cè)試被高度集成到Rails框架并成為Rails應(yīng)用的組成部分了。測(cè)試分三類:?jiǎn)卧獪y(cè)試,測(cè)試數(shù)據(jù)存取接口;功能測(cè)試,測(cè)試控制部分;集成測(cè)試,測(cè)試應(yīng)用的流程。?
          我就不深入測(cè)試的細(xì)節(jié)了—有興趣的讀者可以到Google搜索,能得到大堆資料。上面討論過DSL,我想說說如何將DSL與Rails的集成測(cè)試有機(jī)結(jié)合。為你的應(yīng)用創(chuàng)建測(cè)試DSL,這是可能的,甚至相當(dāng)簡(jiǎn)單。這樣一來,質(zhì)量保證部門和其他測(cè)試人員就可不費(fèi)吹灰之力編寫測(cè)試用例,再不需學(xué)習(xí)復(fù)雜的編程語言。以前面提到的包含消息組件的應(yīng)用為例,我們?yōu)樗鼊?chuàng)建了DSL,并將測(cè)試部分抽象進(jìn)去,那么測(cè)試者就能以如下方式簡(jiǎn)單編寫各類測(cè)試場(chǎng)景:

          kevin = users('kevin')
          kevin.log_in
          kevin.view_new_messages
          kevin.create_message_to('susan')
          kevin.send_message

            這就是我們的DSL。幕后,DSL將為我們描述的場(chǎng)景中的各種功能執(zhí)行必要測(cè)試。使用Ruby,編寫DSL抽象測(cè)試就是這么簡(jiǎn)單。

          學(xué)習(xí)Rails的捷徑
            判斷Rails工具是否適合于你的最好辦法是試用。幸運(yùn)的是,有大量非常好的資源可以幫助你學(xué)習(xí)Rails。首推的應(yīng)該是《Agile Web Development with Ruby on Rails》這本圖書(The Pragramatic Programmers出版)。它堪稱Rails圣經(jīng),也是我讀過的最好并最讓我樂在其中的技術(shù)書。開篇是一些介紹性章節(jié),然后就全程陪同讀者在一個(gè)在線Web商店應(yīng)用里漫步。學(xué)習(xí)Rails(以及其他Ruby的擴(kuò)展框架)的最好辦法是自己動(dòng)手完成一個(gè)應(yīng)用的全部開發(fā),并真正弄懂這些代碼的意思。這本書已經(jīng)出了中文版,但如果購買在線的英文pdf電子書,那么你就能及時(shí)獲得包含大量Rails新特性的更新版本。
            利用《Agile Web Development》學(xué)習(xí)Rails,通常可以掌握Ruby語言的基礎(chǔ),但要想深度把握Ruby,《Programming Ruby》(也由The Pragramtic Programmers出版)將是無可爭(zhēng)議的首選。這是另一本優(yōu)秀的圖書。
            最后,Ruby on Rails的主要站點(diǎn),rubyonrails.org上也有大量文檔信息,還包括一個(gè)wiki。
          啟動(dòng)電腦,試用RoR吧
            最后一點(diǎn),開發(fā)人員欲善其事,必先利其器。Java、PHP和ASP久經(jīng)考驗(yàn)、功能強(qiáng)大,但它們?nèi)狈︶槍?duì)MVC型Web應(yīng)用的專門設(shè)計(jì)。這些語言和框架使創(chuàng)建Web應(yīng)用成為可能,但開發(fā)者常常受制于它們的設(shè)計(jì)初衷和強(qiáng)調(diào)特性與配置的傳統(tǒng)設(shè)計(jì)哲學(xué),而不能專注于應(yīng)用本身的功能和意圖。
            Ruby on Rails針對(duì)Web應(yīng)用量身定做。和傳統(tǒng)工具相比,使用它可以更快更好創(chuàng)建Web應(yīng)用。雖然它還年輕,但步履堅(jiān)實(shí),已經(jīng)和即將使用它的公司正在爆炸性增長(zhǎng)。
            隨著硬件和網(wǎng)絡(luò)帶寬價(jià)格的下降,下一代互聯(lián)網(wǎng)將不再容忍那么笨拙、難以修改和升級(jí)的Web應(yīng)用。這些應(yīng)用必須能夠持續(xù)更新與提升——兩年的版本周期已經(jīng)縮短到兩周,用戶的要求越來越苛刻,他們希望得到真正能夠滿足他們需求和特殊要求的Web應(yīng)用;因此,Web開發(fā)人員必須能夠快速編寫有助于提升他們應(yīng)用的代碼。即使有一行代碼不能直接服務(wù)于應(yīng)用的功能,那也是不能容許的浪費(fèi)。Ruby on Rails就是專為這樣一個(gè)應(yīng)用環(huán)境設(shè)計(jì)的工具。
            好了,啟動(dòng)你的電腦,試用Ruby on Rails吧。像作家的生花妙筆、木匠的慣用鐵錘,Rails也將成為你開發(fā)Web應(yīng)用的利器。

          ?


          作者簡(jiǎn)介:Jonathan Palley是Idapted公司的CTO和創(chuàng)始人之一。該公司是一個(gè)位于北京的硅谷創(chuàng)業(yè)公司,他們開發(fā)的Web和VoIP平臺(tái)徹底地改變了人們學(xué)習(xí)語言的方式。在這之前,Jonathan Palley在斯坦佛大學(xué)學(xué)習(xí)物理。

          posted on 2007-01-21 23:51 77 閱讀(2727) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2007年1月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(12)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          新聞檔案

          相冊(cè)

          API文檔

          java開發(fā)與研究

          にほん

          上海房產(chǎn)

          東京生活

          數(shù)據(jù)庫大全

          編程與開發(fā)

          美國開發(fā)生活

          走向管理

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 浦江县| 彭州市| 克山县| 曲沃县| 揭东县| 东乌| 阿合奇县| 宜阳县| 清丰县| 凉城县| 尉犁县| 周口市| 通州区| 桑植县| 昌乐县| 伊金霍洛旗| 九台市| 白山市| 北流市| 石台县| 开阳县| 滦平县| 泰顺县| 梁河县| 巴彦县| 阿鲁科尔沁旗| 秀山| 阿拉善左旗| 建瓯市| 宁乡县| 东兰县| 广州市| 贵港市| 大冶市| 洛阳市| 同江市| 正镶白旗| 探索| 铜川市| 泰宁县| 平遥县|