一個理想的用戶接口對用戶最好是不可見的-僅在用戶需要時提供選擇,否則并不干涉他們的工作而讓其專注于手頭的工作。然而,這并不是一件容易的事情。如今,我們變得習慣于通過并不十分令人滿意的UI進行日常工作,直到有人向我們展示一種更好的方法。現在,我們才逐漸認識到我們當前的方法在做這些事情時是多么吃力。
由于用于顯示文檔內容的基本web瀏覽器技術又被推進一步進而超出以前它們所能及的范圍,所以,如今的互聯網正在經歷著這樣的實現。
Ajax(異步JavaScript+XML)是一個非常新的名字,為Adaptive Path的Jesse James Garrett所創建。其中,Ajax的某些部分以前被描述為動態HTML和遠程腳本。
Ajax的出現不僅僅是一個新名字的問題。從技術和商業的角度看,圍繞Ajax還有大量激動人心的東西。從技術上講,Ajax實現了web瀏覽器技術中大量的尚未實現的潛力。從商業上看,Google和其它一些主要商家正在逐步使用Ajax技術,從而讓公眾認識到一個web應用程序所能做的事情。
以前我們習慣的典型web應用程序如今正在承受著巨大的壓力,因為逐漸復雜的基于萬維網的服務正日趨成熟并開始應用于互聯網。各種新技術爭相涌現出來以克服這些問題,而Ajax僅使用現有的互聯網技術就能夠更好地表達這些思想。
利用Ajax,我們重用了一堆原有技術但卻擴展了它們原來所能及的范圍。我們需要能夠管理這種我們引入的復雜性。本文將討論怎樣實現這些技術,而且還要討論一下管理大型Ajax工程的問題。我們將介紹Ajax設計模式及其怎樣幫助我們完成工作。設計模式幫助我們捕獲我們的知識和經驗,用我們現在的技術并且使之與其它對象進行通訊。通過把規則引入到代碼基之上,它們就能夠方便創建應用程序-可以據變化對工程加以修改和擴展。使用設計模式進行開發甚至是一種喜悅!
為什么說Ajax是豐富的客戶端?
構建一個豐富的客戶端接口比設計一個WEB頁面要復雜。那么是東西導致我們這樣做的?好處有哪些?什么是豐富的客戶端?
一個豐富的客戶端有兩個關鍵特點:它是豐富的,而且它是一個客戶端。
讓我稍作解釋。豐富指的是客戶端方式。一個豐富的客戶端模型-是指它能夠支持各種輸入方法且能夠直觀又非常及時地作出響應。盡管我們稱其為"豐富的",但是它必須與象字處理器和工作表等現代桌面應用程序一樣好才真正豐富。下面讓我們看一下為達此目的所具體要求的實現技術。
二、比較用戶體驗
在這里,讓我們討論一個工作表程序的實例。當我在工作表輸入一些簡單的公式時,我可以有幾種方式與之交互-現場編輯數據,用鍵盤和鼠標導航數據和通過鼠標拖動重新組織數據。
當我在操作這些時,軟件給我反饋-鼠標光標形狀改變,當我在按鈕上移動時按鈕高亮,選定的文本改變顏色,高亮的窗口和對話框以不同形式顯示,等等(圖1)。
圖1 這個桌面工作表應用程序說明了多種用戶交互的可能性。
|
這些是當今用戶豐富的交互的主要表現。這樣的工作表應用程序就是一個豐富的客戶端嗎?還不是。
在一個工作表或類似的桌面應用程序中,邏輯和數據模型都在一個封閉的環境中運行-在此它們彼此都能清晰可見,但是卻把外界拒之門外(圖2)。我的客戶端定義是一個程序-它能夠與一個不同的獨立的進程通訊-典型地它運行于一個服務器上。傳統地,該服務器比客戶端更大更強壯并且存儲了海量信息。客戶端允許終端用戶觀看和修改這些信息,并且如果有一些客戶連接到同一個服務器上,它允許他們分享該數據。圖3顯示出一客戶機/服務器架構的簡單圖解。
 圖2 一個獨立桌面應用程序的圖解架構。 |
該應用程序運行于其自身的進程之中-在其內數據模型和程序邏輯彼此清晰可見。在同一臺計算機上運行的該應用程序的第二個實例除了經由文件系統之外無法存取第一個實例的數據模型。典型地,全部程序狀態存儲在單個的文件中-當該應用程序運行時它被鎖定以阻止任何信息的同步交換。
 圖3 客戶端/服務器系統和n層架構圖解。 |
該服務器提供一個客戶可以用之進行交互的可共享的數據模型。客戶端仍然維持它們自己的部分數據模型以達到快速存取。多個客戶可以與同一個服務器進行交互,而此時在單個對象或數據庫行良好粒度級上控制的資源被鎖定。該服務器可以是一個單個的進程,就象在90年代以前的早期的傳統型客戶端/服務器模型或由若干中間件層、外部web服務等組成的現代模型。在任何情況下,從客戶的角度來看,服務器具有單個入口點并且可以被認為是一個黑盒子。
當然,在一現代的N層架構中,服務器將能與例如數據庫這樣的后端服務器通訊-這導致了中間件層的出現-它們既充當客戶端又充當服務器端。典型地,我們的Ajax應用程序位于這個鏈的一端上-只擔當客戶端,所以我們可能把整個N層系統看作單個黑盒子-我們把它標記為服務器,以便于我們當前的討論。
我的工作表只專注于它自己的存儲在本地內存和本地文件系統上的數據。如果它架構良好,數據層和描述層之間的耦合可能相當松散,但是我無法把它通過網絡分解與共享。所以,從我們的描述層目標來看,它不是一個客戶端。
當然,Web瀏覽器是客戶端,它連接web服務器并從中進行頁面請求。這些瀏覽器具有一些豐富的功能來管理用戶的web瀏覽,例如后退按鈕、歷史列表和多頁面存儲多個文檔。但是如果我們把一個特定站點的web頁面看作一個應用程序,那么這些通用瀏覽器控制便不能再關聯到應用程序,就象Windows開始菜單或window列表相關于我的工作表一樣。
讓我們看一個現代web應用程序。主要因為每個人可能都聽說過它,所以我們將選擇Amazon-在線書商為例(圖4)。現在,我把自己的瀏覽器指向Amazon站點;因為該站點從我的上次訪問能夠記得我是誰,所以它先給我顯示一個友好的問候、推薦書列表和關于我已購買書的歷史信息。
 圖4 Amazon.com首頁。該系統記得我以前訪問過該站點,其中可導航的鏈接是通用信息和私人信息的混合。 |
從建議列表中點擊一個標題將把我導向一個獨立的頁面(也即,該屏幕閃爍一下,于是我就失去了幾分鐘前可以看到的列表)。于是新頁面中又會充滿各種上下文信息(見圖5)。
 圖5 Amazon.com站點書籍詳細資料頁面。 |
再一次,大量的結合有通用和私人信息的超鏈接出現。盡管如此,大量的細節與圖4所示極為相同-這,由于web瀏覽器的基于文檔的操作,必須被重新轉送到每個頁面。
簡言之,我向你展示了非常豐富的緊密聯系的信息。而且我與這種信息交互的唯一方式是通過點按超鏈接并且填寫文本表單。如果我在瀏覽站點時的鍵盤輸入過程中睡著了并且第二天才醒來,那么在我刷新全部頁面之前我不會知道新的哈里·波特書已經發行。我不可能帶著我的列表從一個頁面轉到另一個頁面,并且我不可能縮放該文檔的一部分來一次觀看多處的內容。
這并不是在詆毀Amazon,在非常有限的限定內它工作得相當優秀。但是與工作表相比,它所依賴的交互模型毫無疑問相當有限。
那么,為什么在現代web應用程序中存在這么多的限制呢?目前,存在很多技術上的原因。因此,現在讓我們作進一步分析。
三、網絡的潛力
互聯網時代的偉大就在于世界各地所有的計算機互相聯系,就象在一個非常大的計算資源之中。遠程和本地過程調用變得很難區分,并且發行者已經不再清醒地了解它們在哪些物理機器上工作。
不幸的是,遠程和本地過程調用是根本不相同的技術。
在網絡上的通訊是昂貴的(它們是慢并且不可靠的)。當一部分非網絡代碼被編譯或解釋時,各種方法和函數就象在其上操作的數據一樣被編碼為存儲在相同的本地內存中的指令(圖6)。這樣,把數據傳遞給一個方法并返回結果就相當直接。
 圖6 本地過程調用序列圖-在此很少的元素如程序邏輯和數據模型都被存儲在本地內存并能彼此直接看見。 |
其實在底層,為了發送和接收數據,很多計算運行于一個網絡連接的兩端(圖7)。實際上,這種計算遠不如沿著物理線路的運行更導致系統的減慢-各級的編碼與解碼遍及通訊的各個方面,從沿著線路傳輸的物理信息,把這些信息翻譯為二進制的1和0,錯誤檢查和重發送,到重新整合該二進制序列。
 圖7 一個遠程過程調用序列圖。在一臺機器上的程序邏輯試圖操作在另外一臺機器上的數據模型。 |
調用函數的請求必須被編碼為一個稍后將被串行化的對象(也即,被轉換成一個線性字節集合)。然后,被串行化的數據被傳遞到應用程序協議(現在通常為HTTP)并且通過物理傳輸發送。
在遠程機器上,該應用程序協議被解碼,并且數據的字節被反串行化以創建該請求對象的一個副本。然后,這個對象被應用到數據模型和一個生成的響應對象上。為了聯系該響應和調用函數,該串行化和傳輸層必須被再一次導航,最后導致一個響應對象被返回到調用函數。
這些客戶端是復雜的但是適合于自動化實現。現代的編程環境例如Java和微軟.NET框架都提供了這種功能的自由使用。盡管如此,當產生一個遠程過程調用(RPC)時,在內部有大量的活動在進行并且如果這樣的調用太自由的話,性能也會受到影響。
因此,通過網絡的調用永遠不會象調用本地內存中的一個方法那么富有效率。而且,網絡的不可靠性(并因此需要重新發送失去的信息包)也使得這種低效在不斷變化且很難預測。在你的本地機器上的內存響應性不僅更好一些而且相比之下可以被很好地定義。
這但與可用性有什么關系呢?已證明,其關系相當大。
一個成功的計算機UI的確需要模仿我們真實的世界期望。該交互的最基本原則之一是,當我們點按某東西時,它能夠立即響應。在點按和響應之間的輕微的延遲都會帶給用戶迷惑并使之分神-把用戶的注意力從手頭的任務轉移到UI本身。
必須做所有的額外工作來穿越網絡常常就足已減慢一個系統,以至于該延遲變得相當引人注意。在一桌面應用程序中,我們需要做出糟糕的可用性設計決策來使得應用程序感覺起來充滿錯誤或不具有響應性,但是在一個聯網應用程序中,不需要我們關心這些!
由于網絡潛力的不可預測性,這種可察覺的錯誤來來去去,并且測試應用程序的響應性也可能變得更為困難。因此,網絡潛力是真實世界應用程序具有可憐的交互性的最通常的原因。
四、異步客戶端
在實際中,我們必須盡量使UI響應獨立于網絡活動。幸好,一段固定時間的響應經常就足夠了,只要它是及時的。讓我們再次看一下實際中的問題。我的早上例程的主要任務之一是喚醒我的孩子們上學。我可以站在他們上面戳他們直到他們起床并穿上衣服,但這是一相當花費時間的方式,留下很長的一段時間我幾乎無事可做(圖8)。
 圖8異步響應用戶輸入序列圖 |
在這個序列圖中,時間的過渡是垂直的。陰影部分的高度指示了我被阻塞進一步輸入的時間長度。
我需要弄醒我的孩子,外盯窗戶,并且忽略了貓。孩子們將通知我-這時他們因要求吃早餐而被正確喚醒。就象服務器端進程一樣,孩子們醒得很慢。如果我使用一個異步的客戶端模型,我將等待很長時間。只要他們能夠咕噥一聲,我就能醒來,然后我就可以繼續輕松地干別的事情并且在需要時檢查他們。
用計算機術語來說,我在此所做的是在一個獨立的線程中激發一個異步的過程。一旦啟動它們,我的孩子們就會在他們自己的線程中自己醒來;而我-父線程,不需要與他們同步,直到他們通知我(通常使用一個請求)。盡管他們正在醒來,但是我無法與他們的客戶端進行通訊,好象它們已經起床并穿好衣服了,但是我能確信它一定會及時發生的(圖9)。
 圖9 一異步響應用戶輸入序列圖。如果我使用一個異步的輸入模型,我能讓孩子們通知我他們開始醒來。然后,當醒來發生時,我能繼續我的 另外的活動并且有一段很短的時間保持阻塞。 |
無論使用任何UI,創建一異步線程來處理任何冗長的計算并且讓它在后臺運行,而用戶繼續處理其它事情都是一種很好的解決方案。當該線程啟動時,用戶必然被阻斷,但是這可能在很短的一段可接受時間之內發生。由于網絡的潛力,一種不錯的實現是把任何RPC當作潛在的冗長過程并異步地處理它。
該問題和這種解決方案都是良構的。網絡的潛力早已出現在老式的客戶端/服務器模型中-這使得糟糕設計的客戶端在試圖到達一個過載的服務器時滯留到令人無法承受的程度。在當今互聯網時代,網絡的潛力使得你的瀏覽器在web頁面間來回切換時經歷了巨大的挫敗。我們不可能消除這種潛力;但是我們知道通過異步地處理遠程調用可以處理它,對不對?
不幸的是,對我們絕大多數web開發者來說,并沒有捕獲到這一點。
HTTP是一個請求-響應協議,該協議是單向的。客戶端可以聯系服務器,但是服務器不能與客戶端開始一個通訊。確實,該服務器不能從一次到另一次的請求中記住客戶端。
多數使用現代語言如Java、PHP或.NET的web開發者都會熟悉用戶會話的概念。HTTP按照它的最初設計良好地工作著,而且它已經被改編來實現更為靈活性的功能。然而,我們的異步回調解決方案的關鍵在于客戶端被再次通知:當創建線程時是第一次而當線程完成時是第二次。直接的HTTP和經典web應用程序模型無法為我們完成這一點。
如Amazon所使用的經典web應用軟件模型仍然是基于頁面概念設計的。一文檔被顯示給用戶-包含一個列表的鏈接和/或表單元素-它們允許它們提交給進一步的文檔。完全有可能以這種方式大規模地與復雜數據集交互,并且如Amazon和其它站點所展示的-完全可以基于這一經驗構建一種商業運作。
這種客戶端方式已經根深蒂固于過去十多年間的每天的商業互聯網之中。友好的WYSIWYG web創作工具把我們的站點可視化為一個頁面集合。服務器端web框架把這種頁面間的轉換建模為狀態轉換圖。經典web應用程序,在頁面刷新時,與不可避免的缺乏響應緊密結合,不可能容易地求助于異步處理器解決方案。
但是Amazon基于其網站已經取得了商業上的成功。當然,經典web應用程序不可能象那樣不可用?為了理解為什么web頁面可以適合于Amazon而不適用于每個人,我們應該考慮一下使用模式的問題。
五、長期與短暫使用模式
軟件可用性專家Alan Cooper對于使用模式下過重要的結論,并且定義了兩個關鍵的使用方式:短暫的和長期的。一個短暫的應用程序可能每天都被使用,但只在是一段時間內且通常只是作為第二活動。而相反,一個長期的應用程序必須每次連續數小時地有效地處理用戶的全部注意力。
許多應用程序其實都是短暫或長期使用的。一個作家的字處理器是一長期的應用程序,例如,其中包括了許多短暫的功能,例如文件管理器(經常嵌入到字處理器中,如一個文件保存或打開對話框),一本字典或拼寫檢查程序(經常是嵌入的)以及與同事交流的一個電子郵件程序等。對一個軟件開發者來說,文本編輯器或集成開發環境(IDE)則是他們長期使用的,還有調試器。
長期使用的應用程序常常也是滿懷激情使用的。請記住,一個良構的UI應該是不可見的。這種使用的一個良好度量是對用戶UI工作流的影響,這樣就提醒了用戶它的存在。如果我只是簡單地把文件從一個文件夾移動到另一個文件夾并遇到一個2秒鐘的等待,我可能比較高興。如果 我在操作一個繪圖程序或在一個繁重調試會話中間遇見同樣的一個2秒鐘等待,我可能變得有點不安。
Amazon是一短暫應用程序,eBay和Google以及大多數的非常大型的公共的基于web的應用程序也是這樣的程序。自從出現互聯網后,權威專家們已經預言了在基于Web的解決方案的沖擊下傳統型的桌面辦公室套件的歸宿。然而,10年過去了,它還沒有發生。基于Web頁面的解決方案對于短暫的使用已經足夠了但是對于長期的使用卻不夠。
六、忘卻Web 幸好,現代web瀏覽器相似于原來的針對遠程文檔服務器的客戶端理想-這極相近于瑞士軍刀相似于一種過時的電石狩獵工具。在沖向創建最引入注目的瀏覽體驗中,交互式小發明,腳本語言和插件都將/正在猶豫不決中關門。
可以把Ajax看作一個針對于瀏覽器戰爭中被誤解的行為不正常的孩子的康復中心。通過提供一些指導和一個可在其中操作的框架,我們能把JavaScript轉換成互聯網中的一個有用的模型成員,它能夠提高一個web應用程序的實用性并且在該過程中不會激怒用戶或給瀏覽器顯示需求量等垃圾信息。為此,有一些成熟的、易于理解的工具可用來幫助我們。設計模式就是這樣一種工具-常用于我們的工作中并且在本文中多次參考。
引入一種新技術是一個技術的和社會的過程。一旦該技術出現了,人們就需要弄明白該用它來干些什么,并且第一步常常是使用它,似乎它是一種原有技術且更為熟悉。因此,早期的自行車被當作是木馬并且沿著地面推著人的腳來騎。隨著這種技術為更廣多的用戶所認識,又一批革新者將發現使用這種技術的一些新的方法-添加了改進如踏腳板,制動閘,齒輪和充氣輪胎。隨著每次改進,自行車變得越來越不象馬了(圖10)。
 圖10現代自行車的發展 |
相同的過程也適用于web技術的發展。Ajax背后的技術能夠把web頁面轉換成某種相當新的東西。為了從根本上理解Ajax技術的潛力,我們必須放開web頁面的概念,并且在這樣做時,要忘卻很多以前我們所做的許多假設。在過去很短的幾個月間由于Ajax一詞的出現,以前我們所用的很多技術都要被拋棄了。
共4頁
凡是有該標志的文章,都是該blog博主Caoer(草兒)原創,凡是索引、收藏
、轉載請注明來處和原文作者。非常感謝。