REST+RIA方案


網站:JavaEye 作者:treenode 發表時間: 2007-07-22 14:11 此文章來自於 http://www.iteye.com
聲明:本文系JavaEye網站原創文章,未經JavaEye網站或者作者本人書面許可,任何其他網站嚴禁擅自發表本文,否則必將追究法律責任!
原文鏈接: http://www.iteye.com/topic/104118

一直很想體會一下使用REST+RIA這種組合開發Web應用效果究竟如何,乘着這幾天有空簡單試驗了一把。



我選擇的案例很簡單,就是《應用Rails進行敏捷開發》一書中的depot應用。爲了簡化問題,我只使用了其中的store控制器部分,並將這一部分改寫成REST+RIA的方式。具體地說,就是:



1、重寫一個控制器(我把它稱爲RestStore),它的功能和Store控制器類似,但只提供RESTful風格的接口;

2、表示層部分用Flex重寫。該層與RestStore控制器通信以獲取必要的後臺數據;



爲了比較的目的,以下將《應用Rails進行敏捷開發》所使用的“經典”方法(Rails作爲後臺,rhtml作爲表現層)稱爲方案一,將我所試驗的方法(RESTful Rails作爲後臺,Flex作表現層)稱爲方案二。除了結構上的差異,這兩個方案所實現的功能和界面基本上是完全相同的。







代碼量比較



方案一:

Controllers(1個文件,57行)

Helpers(1個文件,9行)

Models(5個文件,85行)

Views(6個文件,93行)

CSS(1個文件,227行)

------------------------------------------

共計14個文件,471行





方案二:

Controllers(1個文件,37行)

Models(3個文件,39行)

Views(3個文件,15行)

MXMLs(3個文件,278行)

ActionScripts(4個文件,142行)

CSS(1個文件,76行)

--------------------------------------------

共計15個文件,587行



方案二比方案一要大概多出25%的代碼,這主要是因爲前後臺採用了不同的技術,所以必須寫一些用於轉換數據格式的方法。

需要說明的是,由於沒有詳細統計註釋和空行,因此這個數字並不十分精確,只能作爲一個數量級上的參考。但是代碼量的分佈上還是能看出一些問題來的。方案二比起方案一而言,服務器部分得到了很大的簡化,原因在於(1)視圖部分只提供XML數據,不再負責處理界面;(2)購物車移到客戶端來實現,後臺不再需要Cart和相關的類。



此外,方案一的CSS文件相當長,而方案二的CSS就要小得多。這是因爲方案一的CSS也包括許多用於頁面佈局的部分,而在Flex中,佈局是用佈局容器來實現的,CSS只負責組件樣式。這就使得Flex中MXML比較大而CSS可以稍小一些。(我個人的看法是使用佈局容器進行整體佈局比用CSS更加合理)





通信量比較



在客戶端使用如下操作步驟,這些操作覆蓋了控制器所實現的所有功能。使用HttpLook軟件記錄並比較兩個方案與服務器通信的次數和通信數據量大小。



1、瀏覽首頁

2、添加貨品1

3、清空購物車

4、添加貨品2

5、添加貨品3

6、結賬

7、不輸入任何數據就提交

8、輸入正確的數據並提交



以下爲比較結果。括號內爲服務器返回的HTTP body大小,如果有兩個數字,則分別表示請求數據和應答數據的大小。

比較結果不包含貨品的圖片,因爲這部分數據量對所有方案都是一樣的。
























































 方案一方案2
1GET /store(9834)

GET /stylesheets/depot.css(3263)

GET /javascripts/prototype.js(71260)

GET /javascripts/effects.js(38200)

GET /javascripts/dragdrop.js(30550)

GET /javascripts/controls.js(28911)

GET /javascripts/application.js(148)

GET /images/logo.png(1070)

GET /images/favicon.ico(0)
GET /depotclient.html(4308)

GET /AC_OETags.js(7826)

GET /history.js(1292)

GET /history.html(1272)

GET /depotclient.swf(298104)

GET /history.swf(2656)

GET //favicon.ico(0)

GET /rest_store/list_pay_types.xml(157)

GET /rest_store/list.xml(5281)
2POST /store/add_to_cart/11(1851) 
3POST /store/empty_cart(93)

GET /store(9834)

GET /stylesheets/depot.css(0)
 
4POST /store/add_to_cart/5(1881) 
5POST /store/add_to_cart(1(2065) 
6POST /store/checkout(2718)

GET /images/logo.png(0)
 
7POST /store/save_order(94,3217) 
8POST /store/save_order(129,93)

GET /store(9891)
POST /rest_store/save_order(300,21)
   





可以看到兩種方案在通信方式上的巨大差異。類似的地方是,兩種方案初次瀏覽時都需要加載相當多的附件,不同之處在於方案二要加載的東西中有一個相當大的swf文件,其他內容則都比較小。而方案一則也需要加載幾個比較大的JS文件,這些JS文件大多是Ajax所需要的。



在後續過程中,方案二的優點就體現出來了:由於購物車是在客戶端處理的,結賬的表單也嵌入在SWF中,因此方案二可以在絕大部分時間不必與服務器通信,只在最後提交表單的時候需要再次請求服務器。方案一雖然每次請求的數據量都不大,但是請求次數相當頻繁,對於服務器來說負擔仍然相當沉重,而且請求次數越多,由於網絡問題等原因出錯的可能性也越大。



仔細觀察表中的數據也能看出一些有意思的結論。請看方案一中的步驟2和步驟3:步驟3清空購物車使用的傳統的Web方法,即向服務器發出請求,然後重新載入整個頁面;步驟2添加一件貨品,使用的是Ajax方法。兩個步驟其實數據量差不多大小,步驟2還要多出一個product_id參數,但是無論從請求數量(1:3)還是數據量大小(1851:9927)都表明Ajax比傳統的全頁面刷新方法要優越得多。不過在這個方面,RIA走得更遠:完全不需要向服務器請求,客戶端本身就可以完成相當一部分工作。







結論



REST+RIA是一種新興的Web應用結構,這種結構具有如下的優點:



1、將表現層與後臺徹底分離



傳統的Web表現層技術總是依賴於特定的服務器編程語言的。比如你用JSP編寫頁面,就意味着服務器後臺必須使用Java,如果後來決定改用ROR,那麼除了用rhtml重寫表現層以外大概沒有什麼更好的辦法。而使用RESTful風格的接口意味着服務器只需要提供資源,不論後臺使用Java,Ruby或.Net來實現,對錶現層都完全沒有影響,哪怕把後臺整個換掉也不需要重寫表現層,這也意味着表現層是完全可重用的。考慮到真實的項目中對錶現層的修改往往是最麻煩且工作量極大的部分,這項分離意義重大。



要將表現層與後臺分離,其實也有其他的一些技術方案可選。以前出現過的兩種比較常見的辦法:(1)服務器提供XML數據,然後用XSLT轉換爲HTML或其他格式;(2)服務器提供Web Service接口,用支持WS的客戶端訪問。不過這兩種方法可能也存在一定的問題,最後並沒有真正流行開來。Web Service更多的用在異構系統整合而不是系統內部通信上。





2、方便程序員和美工協同開發



在頁面中嵌入代碼是好是壞?問題不在於代碼本身,而在於這樣一來美工和程序員的工作難以協調,任何一方做出修改,都必須複覈自己的修改是否破壞了對方的工作。RESTful風格的接口只提供資源數據,不暴露服務器上的任何實現細節,這對美工和程序員來說絕對是個好消息:只需要約定服務器提供數據的格式,美工就可以完全按照自己的節奏去設計和測試頁面,程序員也可以專心實現後臺邏輯,彼此都不需要擔心破壞對方的工作,可以實現完全的並行開發,這是以往任何Web開發技術都沒能做到的。





3、有利於採用快速原型的開發方式



在上面已經提到過,在這種方式下,美工和程序員可以完全並行工作。即使在還沒有實現任何後臺邏輯之前,只要先寫一個符合格式的Xml佔位文件,表現層就可以開始設計,不論後臺開發速度快慢,表現層都可以儘快提供一個可以工作的原型,對於儘早審覈需求和獲得用戶反饋都是非常有利的。





4、合理分配負載,減輕服務器壓力



大多數Web應用在負載的分配問題上其實是非常不合理的:服務器承擔着成千上萬的用戶請求,每時每刻都在忙碌之中,而客戶端機器在這個時間裏只是傻傻的等待響應,根本無事可做。從前面的測試結果可以看到,RIA的方案需要一次性下載較大的數據,但在這之後客戶端可以承擔相當一部分工作,避免頻繁請求服務器,不僅在資源分配上更加合理,也能夠讓服務器同時承載更多的用戶。





5、提高用戶體驗



減少服務器請求不僅是資源問題,也關係到用戶體驗,頻繁的頁面閃爍是相當糟糕的。Ajax可以在相當程度上緩解這一問題,

但是Ajax並不太適用於大範圍的頁面變化和頁面跳轉,一般的Web應用中使用頁面跳轉的比例仍然遠高於使用Ajax的比例。當網絡情況不佳或服務器繁忙時,等待服務器響應也是很惱人的事情。

一個RIA(如Flex)應用中通常包括多個頁面,在頁面之間切換不會有停頓,甚至不太大的應用可以One page one application,更不必擔心愉快的衝浪過程中突然拋給你一個404或500錯誤(這對心臟相當有好處)。



(PS:不過世界上的事情有時候也難說。我的確知道有這麼一些人,他們覺得看瀏覽器頁面閃動的白屏比看Flash的平滑窗口漸變更舒服。除了習慣成自然外,我實在很難想出有什麼別的理由可以解釋這個問題)









但是這種開發方式也有一些問題:



1、至少在目前,Flex面臨着和瀏覽器一樣的限制——只支持GET/POST調用,還不能完整支持REST所要求的全部動詞。雖然這個問題有一些臨時的解決辦法,不過需要在後臺和表現層上都必須寫一些hack代碼,並不是很優雅。上面的例子也僅使用了GET/POST調用,還不能算是很嚴謹的REST方案。我們期待下一個版本能解決此一問題;



2、這種方式的開發代碼量要略大於純ROR的方法。Flex中使用的Actionscript語法比較類似於Java,仍然需要寫很多大括號,對於循環也只能用笨拙的for ...。動態語言在生產力方面的優越性還是相當明顯的。當然,比起Java或ASP.Net來說,Flex的代碼量或許已經算是很少了。



3、關於如何組織Flex程序,目前還沒有一致的意見,因此在Flex程序中還沒法體現慣例優於配置的原則,仍然要編寫一些自定義代碼;



4、Flex編譯後的程序通常比較大(普通規模的一般有200~300K,嵌入資源的話更多),在低速網絡上首次下載會比較慢。據說Flex 3已經在着手解決此問題。









感想:



RIA(這裏的RIA特指Adobe Flex和M$ WPF/Silverlight等,不包括Ajax)現在還是一種褒貶不一的技術。讚賞者認爲,RIA結合了B/S結構和C/S結構的優點,安裝部署的代價接近於前者而表現力上接近於後者;批評者則認爲RIA在兩方面都算不上最好:部署上不如B/S(需要安裝瀏覽器插件)而表現力不如C/S(因爲安全原因不能訪問全部本地資源)。其實這兩種說法都有道理。世上沒有一種技術能具有所有的優點而沒有缺點,也沒有一種技術能包打天下。DHH說RIA沒用,現代的Web技術足夠發達了,我覺得此說不確。目前的Web應用或許有80%用HTML加上一些Ajax就夠了,但餘下的那20%呢?那些是用純Web方案很難甚至沒辦法解決的領域,雖然少,但是硬骨頭也要有人來啃。



因爲REST和RIA目前都不能算比較成熟的技術,即使在這個很小的例子裏也暴露出一些問題,大規模採用這種解決方案還是不太可行的。不過這些問題大多已經有人開始想辦法去克服,相信未來會逐步得到解決。



事實上在這個簡單的例子裏我已經感覺到這種方案“分離關注點”帶來的好處。在ROR的方案裏,我需要同時考慮:在Controller裏面提供什麼數據,在View中怎麼展示這些數據,思路總是在Model,Controller和View中來回切換。但是在REST+RIA的方案下,我可以在實現Controller的時候完全不考慮表示層,在實現界面的時候也完全不用考慮後臺,思路非常集中,也容易專注於去思考一些設計上的問題。這是一次很好的開發體驗,也讓我有足夠的信心說:儘管還存在一些問題,但是REST+RIA的方案必將有着光明的前途。




《 REST+RIA方案 》 的評論也很精彩,歡迎您也添加評論。查看詳細 >>

推薦相關文章:
  [翻譯]Ext vs. Dojo
  瘦ajax線路圖




JavaEye推薦
上海樂福狗信息技術有限公司:誠聘技術經理和開發工程師
免費下載IBM社區版軟件--它基於開放的標準,支持廣泛的開發類型,讓您的開發高效自主!
京滬穗蓉四地免費註冊,SOA技術高手匯聚交鋒.
上海:優秀公司德比:高薪誠聘 資深Java工程師
廣州:優易公司:誠聘Java工程師,開發經理
上海:尤恩斯國際集團:誠聘開發工程師
北京:優秀公司NHNChina招聘:WEB開發,系統管理,JAVA開發, DBA


發佈了0 篇原創文章 · 獲贊 0 · 訪問量 1458
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章