改變Web應(yīng)用的開發(fā)方式(一) |
改變Web應(yīng)用的開發(fā)方式(一) ----由Ajax引起的思考 作者:ZZ剛 轉(zhuǎn)載請注明出處(http://spaces.msn.com/members/zigzagchen) 引子 如果讓你說出在最近在Web開發(fā)領(lǐng)域中被炒得最火的一個詞,八九不離十將會是Ajax。套用魯迅先生說過的一句話:“世上本沒有概念,炒的人多了,便成了概念”。其實(shí)這個概念之所以能夠被炒起來,除了Google等公司給我們炫了幾個很Cool的Ajax應(yīng)用之外(Gmail, Google Suggest, Google Maps),更關(guān)鍵在于它為我們提供了一種Web開發(fā)的新思路 (Ajax: A New Approach to Web Applications )??赐赀@篇給Ajax命名的文章,首當(dāng)其沖的是異步調(diào)用,通過XMLHttpRequest這一手段,我們可以使用戶不用在進(jìn)行每一個操作后干等Web的響應(yīng),從而提升了用戶流暢的體驗(yàn)。 這個是這篇文章的核心,也是Ajax吸引人的一個亮點(diǎn)。但是今天我們要討論的,卻是文中提出的另一張圖(圖1),雖然Jesse James Garrett沒有對其進(jìn)行詳盡的描述,但是它同樣能給我們帶來一定的思考空間。 傳統(tǒng)的Web開發(fā)方式及其發(fā)展歷程 如圖1所示,左邊是傳統(tǒng)的Web開發(fā)方式:Web Server接受客戶端傳送過來的HTTP請求,進(jìn)行解析,與后臺交互進(jìn)行業(yè)務(wù)處理,再把結(jié)果渲染成HTML,最后將其傳到瀏覽器。雖然這種方式歷經(jīng)了多年的發(fā)展,我們也有不少的開發(fā)框架和工具可以使用,但是Web應(yīng)用的開發(fā)仍顯得比較復(fù)雜低效。我們通過回顧Java Web開發(fā)的發(fā)展歷程來分析一下這個問題。 Sevlet為Java Web編程的早期規(guī)范,把Http請求與響應(yīng)被封裝成Java對象。在這段時期,整個Web應(yīng)用基本僅由程序員來完成,他們在Servlet程序中從Request中取得客戶端傳送過來的參數(shù),進(jìn)行處理后將結(jié)果寫回到Response對象的輸出流中,這種方式無論對開發(fā)人員或是用戶來說都是比較痛苦的,程序員需要在程序中寫入大量重復(fù)枯燥的HTML輸出語句,而且這種方式也很難在HTML的美工方面做得很好,所以對于用戶來說,他們只能看到一些粗糙簡陋的頁面。 為了解決這個問題,JSP等動態(tài)網(wǎng)頁技術(shù)出臺了,首次在頁面與程序分離方面邁出了一步,程序員可以在美工人員完成的HTML頁面中嵌入程序代碼,用來控制頁面中動態(tài)部分。但是由于JSP規(guī)范對頁面中Java程序沒有太大的限制,對哪一些程序應(yīng)該放在動態(tài)頁面中,哪一些程序需要放在后臺程序中處理也沒有一定的規(guī)范。導(dǎo)致了在很多的Web項(xiàng)目中,大量的Java代碼充徹于HTML Tag的字里行間,給美工與程序員都帶來了不少痛苦。 為此,Craig R. McClanahan等一些有見解的開發(fā)人員開始提出了Web開發(fā)的model2,將經(jīng)典的MVC模式導(dǎo)入到Web開發(fā)中,出現(xiàn)了Struts這個至今仍非常流行的Web框架,在架構(gòu)上,它把瀏覽器提交的請求交給一個統(tǒng)一的Servlet控制器,由控制器通過讀取控制文件將事件分配到相應(yīng)對象模型(Actions)中,實(shí)現(xiàn)了對Request事件響應(yīng)的對象封裝。而在頁面渲染方面,提供了一套與HTML形式類似的Taglib庫,意圖于減少HTML與Java程序間的異構(gòu)性,更好地實(shí)現(xiàn)頁面與邏輯分離。后來的出現(xiàn)的WebWork, Spring MVC基本上繼承了Struts中的MVC思路,只是在事件分派,頁面渲染的靈活性上進(jìn)行了提高。但是這種所謂Web MVC的方式并不能徹底解決Web開發(fā)中的痛苦,由于Action的激活基于每一個頁面跳轉(zhuǎn)產(chǎn)生的Request請求,對于復(fù)雜的頁面事件交互,Action的粒度與頁面中狀態(tài)的保持都是比較麻煩的問題。而且由于TagLib沒有一個統(tǒng)一的規(guī)范,自定義性太強(qiáng),使得嵌入它的頁面很難被主流的HTML編輯器支持,始終不能擺脫頁面與程序分離的問題。 在基于Request,對Action進(jìn)行封裝的框架之外,還有另一個Web框架的分支,那便是JSF等以對可視化組件進(jìn)行封裝為基礎(chǔ)的架構(gòu)。它力圖將HTML元素的屬性和事件的監(jiān)聽都封裝在后臺的對象中,為開發(fā)者屏蔽掉處理HTTP Request/Response方式帶來的事件分派,狀態(tài)保存等麻煩。這種方式在MS的.net開發(fā)中一直被提倡,希望Web程序的開發(fā)能像VB中的一樣,利用強(qiáng)大的IDE,制作布局,畫出控件,為控件指定監(jiān)聽器并書寫響應(yīng)程序。但是這種方式也存在一定的問題,因?yàn)锽/S的Web架構(gòu)畢竟與單機(jī)或是胖客戶端不同,如果連結(jié)到服務(wù)器的并發(fā)用戶較多時,這種將組件的事件監(jiān)聽,狀態(tài)保持和渲染的工作都交由后臺程序的方式必將對服務(wù)器資源提出更大的挑戰(zhàn)。 總結(jié)以上各種Web開發(fā)方式所面臨的問題,其根本癥結(jié)可歸于以下三點(diǎn): 一是由于HTTP基于請求/響應(yīng)范式。傳統(tǒng)應(yīng)用中瀏覽器發(fā)出請求,服務(wù)器針對每一個請求返回一個HTML頁面。 二是由于HTML作為一個用于內(nèi)容布局的結(jié)構(gòu)化標(biāo)志語言,與進(jìn)行數(shù)據(jù)/邏輯處理的編程語言存在異構(gòu)性。 三是由于Web應(yīng)用以服務(wù)器為中心,Web開發(fā)需要考慮服務(wù)器端的負(fù)載問題。 Ajax能給我們帶來什么? 對于這三大難題,Ajax方式能給我們帶來解決的途徑嗎? 我們回頭看看圖1的右邊。與傳統(tǒng)的Web應(yīng)用開發(fā)方式比較,它在瀏覽器端添加了一個層----Ajax engine,由用戶產(chǎn)生的頁面事件交由這個引擎處理,它負(fù)責(zé)向服務(wù)器發(fā)送請求,服務(wù)器傳回的是業(yè)務(wù)數(shù)據(jù)而非HTML,引擎接受之后,進(jìn)行渲染,通過瀏覽器的解析在頁面上顯示出來。說白了,就是將事件監(jiān)聽與頁面渲染的工作交給了瀏覽器,而后臺服務(wù)器只負(fù)責(zé)業(yè)務(wù)邏輯的處理。 在Ajax方式下,HTTP基于請求/響應(yīng)的范式仍然沒有變化,但是由于有XmlHttpRequest對象(Ajax engine的核心)的支持,我們不需要像以前那樣將每一次請求發(fā)到服務(wù)器后,由服務(wù)器解析請求再進(jìn)行事件發(fā)配,之后返回刷新用的HTML頁面。在新的方式下,由于事件的監(jiān)聽和處理在瀏覽器內(nèi)部實(shí)現(xiàn),它的反應(yīng)周期可以被縮短,事件的處理粒度可以更方便的做到更細(xì),而且由于支持異步方式發(fā)送Request請求和接受Response響應(yīng),用戶事件的控制有了更大的靈活性。 在Ajax方式下,HTML與程序的異構(gòu)性仍然存在。但是由于把頁面渲染放到瀏覽器中,使得我們可以通過HTML DOM對HTML的各個組件以對象的方式進(jìn)行訪問與控制而不是刷新整個頁面,使得頁面的渲染變得更加靈活,簡便,豐富多彩。想想別扭的JSP Tag或是與HTML似近實(shí)疏的TagLib,還有Velocity等模版語言,他們的Tag被插入到HTML原本的Tag中,指揮服務(wù)器程序?qū)Ρ凰莸腍TML進(jìn)行邏輯操作從而來達(dá)到動態(tài)渲染頁面的目的,不可避免的存在頁面結(jié)構(gòu)與程序邏輯混雜的問題。 在Ajax方式下,Web程序仍然以服務(wù)器為中心,但是由于事件處理與頁面渲染的工作可以由瀏覽器來擔(dān)當(dāng),從而減輕了服務(wù)器的負(fù)擔(dān)。 Ajax開發(fā)方式存在的問題 既然Ajax方式存在以上優(yōu)點(diǎn),XmlHttpRequest,HTML DOM也不是最近才浮現(xiàn)的,為何這種方式到如今才進(jìn)入我們的視野,而未能成為Web開發(fā)的主流呢?原因有以下幾點(diǎn): 1. 它依賴于瀏覽器。而至今各不同廠商的瀏覽器,甚至同一廠商瀏覽器的不同版本,對XmlHttpRequest與HTML DOM的使用方式皆有所區(qū)別。 2. 它依賴于JavaScript。從而有帶來了以下問題: Ø 用戶可以很方便地關(guān)掉瀏覽器的JavaScript支持。從而使Ajax無用武之地。 Ø JavaScript本身的語法要求過于靈活松散,降低了它的可讀性 Ø 沒有強(qiáng)大好用的IDE與Debug工具 Ø 對于開發(fā)人員來說,在習(xí)慣于傳統(tǒng)的Web應(yīng)用開發(fā)之后,大部分人對其不重視,認(rèn)為它只是做頁面即時校驗(yàn)或一些頁面效果的小伎倆 問題的解決 雖然Ajax存在著這樣的問題,有些看起來甚至是致命的,但畢竟它還是被炒起來了,火起來了?;贏jax的網(wǎng)站春筍般涌現(xiàn),用于Ajax開發(fā)的框架與工具也嶄露頭角(Google開放了AjaXslt,微軟推出了Atlas,JSF中加入隊Ajax的支持)。這些都給我們一個信號,會有越來越多的網(wǎng)站與應(yīng)用傾向于這種方式。為此,瀏覽器廠商會考慮到這個問題,雖說標(biāo)準(zhǔn)化不是一朝一夕的事情,但是大家會朝這個方向走得更近而非更遠(yuǎn)。隨著Ajax應(yīng)用越來越多的閃亮登場,用戶關(guān)掉JavaScript的可能性進(jìn)一步降低。這是發(fā)展的趨勢,但就目前的現(xiàn)狀來說,支持XmlHttpRequest, HTML DOM, JavaScript的瀏覽器也已是Web程序客戶端的最大平臺,而且將各瀏覽器間使用差別封裝起來的Ajax engine也已經(jīng)出現(xiàn)。從外部環(huán)境來講,Ajax的推廣應(yīng)用已經(jīng)不成大的問題。 剩下的就是開發(fā)人員的問題了。對于JavaScript,它能做到什么,能從何種程度上改變我們開發(fā)Web應(yīng)用的方式?JavaScript有其先天不足,但是如果我們以O(shè)O的思想來看待它,利用并編寫可重用度高的JavaScript組件,把前后臺組織成一個新的框架,你會發(fā)現(xiàn),比較起以往的方式,Web開發(fā)確實(shí)變得簡單了。我將在本文的第二篇中介紹對這樣框架的特性要求和實(shí)現(xiàn)手段。而至此,需要我們做的只是一點(diǎn):觀念的轉(zhuǎn)變。 |