1 B/S為何難於提供好的用戶交互體驗?
這裡頭的最大問題有幾個:
(1)無狀態的HTTP協議
Windows窗體間可以通過內存直接交換信息,但作為B/S架構通訊基礎協議的HTTP是無狀態的。
如果將浏覽器看成是客人,Web Server看成是旅館,在HTTP協議的管理之下,會出現這種情況:不管某客人來訪多少次,Web Server都將其視為第一次的訪客。這樣一來,客人每次都得帶齊身份證件供旅館工作人員“驗明正身”。
HTTP協議的無狀態,導致Web Server的“六親不認”,這固然能增加Web Server的吞吐量,卻給應用系統的開發帶來了麻煩。因為應用系統中往往有許多業務處理流程,天生就是信息流轉的,即原始數據從一端進去,從另一端出來時應該已經過某些處理,怎可想象整個業務流程中的信息會流失?於是,在HTTP各請求間共享信息就成了件麻煩事,這就是HTTP請求的“狀態保持”問題。每個B/S系統都必須解決這個問題。微軟想了一些“歪招”,比如充分利用Html網頁的中隱藏域,再在Web Server上做些手腳,於是ASP.Net擁有了一套在各個HTTP請求之間維持狀態的技術:Session,Cookie,VIEwState,Profile,Application。
然而問題並沒有完全解決。比如,C/S系統中常見的收集用戶輸入信息的對話框,主窗體與對話框之間有著信息的交換(又分為兩種:模式的和非模式的,前者對話框不關掉,主窗體不能被激活),在B/S架構之下,由於浏覽器的每個請求是獨立的,要在兩個獨立的浏覽器窗口間實現類似於模式對話框這種直接的信息交換,我還真不知道該怎樣干。
AJax使用以下這種的方法來“摸擬”出模式窗體:將主窗體與對話框“合二為一”,對話框在Html中就是一個div元素,平時是隱藏的,需要時再顯示它。微軟的AJax Control Toolkit中甚至為這一功能設計了一個控件。諸如此類的小伎倆,在B/S開發中不勝枚舉。
可以看到,許多在C/S輕而易舉就可實現的功能,在B/S中要實現則大費周章。
(2) 特殊的運行環境——浏覽器
B/S系統的前端運行環境是浏覽器,這就帶來了諸多的限制,不能干許多事,比如直接訪問硬件(例如打印機),也無法充分利用硬件的資源。例如,現在的新電腦都是雙核的,你能直接用JavaScript加Html寫出一個多線程程序以充分利用這兩顆“奔騰的芯”?
而C/S系統則直接運行在OS(操作系統)之上,可以調用OS提供的所有功能,這種限制就不存在了。
(3)尴尬的Web客戶端編程語言——JavaScript
傳統的C/S程序,可以使用為數眾多的各種開發語言,尤其是象C++,Java,C#之類主流面向對象語言,功能強大,使用方便,各種開發工具齊備,已非常成熟。
與此相反,B/S前端所使用最多的編程語言Javascript,不僅不讓人喜歡,甚至讓許多程序員“恨之入骨”,將“用JavaScript編程”看成是件苦差事。
讓我們來看看JavaScript的兩大硬傷。
首先,缺乏清晰而統一的編程模型。
Javascript雖然名字中有一個Java,並采用了類似的語法,但與真正的Java並無關系。唉,她本身是一只丑小鴨,總想著攀上天鵝這門親,卻沒想到別人並不買賬。
Javascript用到了許多對象,但說它是面向對象的吧,又實在難以令人信服(面向對象編程的基本單元是類),比如它沒有類似於C#等主流面向對象語言的關鍵字class,到處是一個個的函數,這就使所有的代碼難於以類的方式清晰界定;同時,它又不是結構化的(結構化編程的基本單元是函數),因為浏覽器在解析Html文檔時,是采用流式解讀方式,從而導致一些JavaScript代碼被放在函數之外,在解析Html文檔時直接執行,而另一部分放到函數中的代碼,則多采用事件驅動的方式運行,這就帶來了復雜的程序執行流程,遠不如純結構化編程中統一采用函數調用的編程方式簡潔。
這樣看來,JavaScript兼具面向對象,結構化,非結構化三種編程方式的特點,但卻弄得不倫不類,沒有一個清晰而統一的編程模型,難於寫出結構清晰易於維護的代碼,反而帶來了許多混亂。
其次,JavaScript的另一硬傷是它的浏覽器運行環境。
由於歷史的原因,不同的浏覽器,甚至同一浏覽器的不同版本,其編程模型都有或多或少的差別,因而不得不寫代碼檢測浏覽器類型,比如需要為IE寫一套代碼,又為Firefox寫另一套。這實在是一件麻煩事。
上述這些問題,幾乎是B/S架構系統“與生俱來”的“缺陷”。先天不足後天補,人們想出了許多招數來解決這些問題。AJax是眾人看好的希望之星。
2 希望之星——AJax
這些天來,我系統地了解了一下微軟的AJAX框架。發現這一框架的復雜遠遠超過我原先的估計,微軟設計AJax框架的工程師們,將各項web開發技術的潛力發掘得很深,在很大程度上彌補了前面提出的問題。
(1)對JavaScript語言的擴充:
微軟通過提供封裝好的AJax Library,增強了Javascript的面向對象特性,可以方便實現繼承,定義接口,序列化對象,引發事件,反射類型等功能,雖然比真正的面向對象語言(比如Java/C#)還有差距,但能將“丑陋”的JavaScript打扮得可以見人,也算是功力不凡。
(2)大幅度提升浏覽器端代碼的功能
在AJax Library支持之下,配合增強功能的Javascript,在浏覽器本身的支持之下,可以在浏覽器中寫JavaScript腳本,方便地向服務器發出異步請求,實現頁面局部刷新,並可以直接調用Web Service。
(3)引入基於組件的開發(CBD)方式
基於組件的開發(CBD)早已是面向對象系統的主流開發方式,雖然現在SOA(基於服務的架構)炒作得熱鬧非凡,但要達到CBD那樣的成熟程度,還需要時間。
對於JavaScript而言,別說SOA,能實現CBD都很困難。
為了實現CBD,微軟給JavaScript“大補特補”,增強了許多特性,基於Microsoft AJax Library,程序員可以開發三種類型的可復用組件:None_Visual Component(不可視的組件,相當於面向對象系統中的一些提供公用功能的類)、Behavior(行為,擴充現有Web控件的功能)、Control(擁有可視化界面元素的Web控件)。
尤其是AJax Control ToolKit中提供的幾十個控件,基本上實現了B/S對C/S用戶界面大部分特性的摸擬,是這一新編程模型應用的典范。
微軟對JavaScript編程模型的增強,使軟件工程師終於可以用CBD的開發方式開發Web客戶端代碼。我認為,這是一個進步。
(4)增強的服務器端能力
為了增強浏覽器端代碼的能力,必須通過服務器端予以配合。AJax本身就基於Browser與Web Server相互支持的編程模型(Web Server提供數據服務,Browser提供XMLHttpRequest對象可向Web Server發出異步請求,當數據回來時,程序員可以用JavaScript編寫代碼實現對網頁的動態局部更新)。
通過AJAX Extension,微軟增強了服務器端ASP.NET框架的功能。並將常用的功能外化為簡單的Web控件,比如AJax的核心控件ScriptManager,用於定義頁面可更新區域的UpdatePanel,還有用於增強現有ASP.Net控件的位於AJax Control Toolkit中的幾十個Extender控件(即附加到現有控件上的控件,其目的是給現有控件擴充新的功能)。
擁有了這些控件,開發Web前端程序就類似於在VB中設計窗體了。現在不僅僅是可以繪出類似於Windows窗體的界面,而且通過利用AJax的異步請求與頁面的局部刷新技術,在Web服務器的配合之下,可以在用戶體驗上逼進Windows窗體。
不管多少人如何看不起VB,但VB所帶來的可視化編程普及浪潮,的確影響深遠,微軟推動JavaScript編程走向這一步,也是大勢所趨。為了提高Web 開發的效率,必須走這一步。
然而,需要指出的是,不管後天如何“進補”,畢竟“先天不足”,B/S架構要在用戶體驗這點上超過C/S,還是非常困難。
3 未來:B/S與C/S,誰主沉浮
由於管理與部署的簡便性,B/S架構成為當今許多信息系統的首選,然而,用戶是追求好的使用體驗的,大體總結起來,有以下要求:
(1)漂亮的界面。這點B/S有優勢。
(2)方便的輸入。比如許多用戶都希望能不用鼠標就可以錄入數據,或者是通過簡單的點擊實現數據的自動填充,在B/S架構下實現起來比較麻煩,AJax可以在一定程度上解決這個問題。
(3)閃電般的速度。對於C/S而言,要實現響應速度快,有許多的法子可想,可B/S就不容易了。由於受到浏覽器的限制,客戶端強大的硬件資源幾乎是被閒置的。另外,網絡速度是B/S架構的瓶頸,除非帶寬能有快速的增長,否則,WWW就是World Wide Wait。
C/S雖然擁有好的用戶體驗,但它的問題在於開發跨越整個互聯網的分布式系統困難,而且由於需要安裝客戶端,系統更新與組件版本管理就成了一個大問題,此外,不象B/S架構中只需考慮服務器端的問題,在C/S架構由於多用戶同時訪問服務器,各組件間的調用和依賴關系復雜,在處理多線程訪問共享資源,事務處理等方面必須同時考慮客戶端與服務器端,吞吐量受到大的限制。因此,C/S多建構於局域網內,供企業內部使用。
目前基本上是B/S與C/S共存,隨著諸如AJax之類B/S技術的廣泛應用,B/S不斷攻城掠地,占有上風,但不可能將C/S徹底地“打垮”。
比較有意思的是:象微軟這樣的大公司,是如何看待B/S與C/S發展前途的?
我等普通開發者,沒有機會直接與微軟高層對話,但可以從其公司的產品發展路線看出一些端倪:
微軟似乎並未認為B/S代表著未來的技術發展方向,相反,它的許多行動,都向著拋棄浏覽器的方向在走。
首先,微軟簡化了C/S的開發與部署問題,推出了Smart ClIEnt技術,讓C/S客戶端程序的更新可以無需人工干預,自動進行。
其次,微軟努力彌補B/S與C/S兩者間的鴻溝,在設計ASP.Net時,毅然拋棄已取得不錯業績的ASP,直接采用類似於VB的“可視化控件+事件驅動” 編程方式,甚至將Web 頁面也稱為“Form”——Web Form。
第三,微軟可能認為AJax是一種過渡性質的技術。
微軟在AJAX上遲遲不見動作,直到看到由於Google等公司成功應用AJAX技術提升Web用戶體驗而導致AJax的迅速竄紅時,才行動起來,給ASP.Net加上AJAX擴展,整個過程中顯然行動並不積極,投入的資源也並不多,這與當年微軟與網景公司展開浏覽器大戰時完全不一樣。但從其在VS2008中將AJax Extension內置為標准配置,並直接集成JavaScript的調試功能到IDE中,說明微軟還是面對現實的,它承認AJax擁有重要的地位與較大的發展潛力。
其實,我分析微軟的野心是“一統天下”,拋棄浏覽器,徹底統一B/S與C/S。
這點在.Net 3.0/3.5中看得很清楚。
首先,微軟用WCF統一了DCOM,.Net Remoting等主要用於C/S的技術,集成了原先位於COM+中的許多企業化開發特性,連同主要用於B/S架構的Web Service技術,統一地抽象並封裝為可復用的WCF Service。很明顯,微軟要將信息系統開發模式由CBD轉為SOA(即未來的系統是組裝Service,而非組裝Component)。
其次,微軟拋棄了非常成熟的Window桌面程序編程模型(Win32 API+消息/事件驅動)引入了一個全新的WPF編程框架,其中的一個重大的革新是符合XML規范的XAML(應用程序標記語言)的出現。XAML用XML格式純文本文件來描述應用程序界面。
我們可以很容易地將XAML與XHTML進行類比。浏覽器解析XHtml代碼,生成可視化的網頁界面,而XAML則由.NET Framework 虛擬機負責解析,在Vista中,由於Vista直接集成.Net Framework 3.0,就可以將Vista看成是一個超級浏覽器,由它負責讀入XAML生成用戶界面,並實現其所有應用程序功能。
這樣一來,一種新的編程模型浮出水面,不管是B/S還是C/S的系統,其方式都是統一的:讀入XAML代碼à解析à呈現à接收用戶輸入à處理數據à顯示結果。
在這個編程模型中,浏覽器成了一個旁觀者,不再是客戶端應用的核心。
新編程模型的運行平台是全功能的OS,而非功能受限的浏覽器。這個區別是巨大的,一個運行於OS之上的浏覽器,其功能怎能和OS自身相比!
現在可以通過按面向對象方式組織起來的操作系統API(應用程序編程接口)方便地調用操作系統的各種功能,充分利用客戶端的硬件資源(比如可以很容易地在.Net Framework之上開發多線程程序,“壓搾”雙核CPU的工作能力)。用戶界面都用XAML來描述,這就統一了B/S與C/S的界面層技術。
WPF最適合的運行環境是Vista操作系統,它的一個功能子集,現在稱為Silverlight,被實現為一個浏覽器插件,從而讓WPF程序也能跑在傳統的浏覽器中。由於Silverlight和Vista本身都可以解析XAML,所以,現在可以用XAML只寫一套界面代碼,就同時適用於B/S與C/S,並獲得相同的用戶體驗。
由於B/S和AJAX存在著一些先天不足,如果將經過AJax增強功能的B/S系統比喻為一個舞者,那麼,這其實是一位帶著鐐铐跳舞的舞者,而微軟公司的想法是,與其不斷想法減輕這一鐐铐的重量,為何不干脆直接拋棄這一鐐铐呢?
微軟推出WPF與WCF,就是這樣的一個嘗試。
應該來說,微軟公司的這套發展戰略是建立在對現有B/S與C/S各自的優缺點分析的基礎之上而制訂的,有它的科學性,也考慮到了自身的商業利益。但這一戰略最終實現還有許多困難,因為即使強大如微軟,也無法一統江湖。微軟的對手與微軟一樣聰明,技術進步同樣迅速。
可以斷言,由於信息系統應用的延續性,在相當長的一段時間內(也許有三五年,也可能有五到十年),B/S與C/S將同時並存,由於B/S許多突出的優良特性,在與C/S的競爭中將占上風,這個局面不會有大的改變。對於AJax,作為B/S系統的一個重量級武器,雖然很有效,但存在不少缺陷,我對於它的未來發展,抱有謹慎的樂觀態度,不過,作為一名Web 開發者,應該去了解並應用這一技術。
未來的格局到底如何,某種技術到底有沒有前途,都不是由個人說了算的。我想,B/S與C/S之爭最終的格局,將是多方面因素共同博弈的結果。對於個人而言,必須與時俱進,及時調整自己的行動和戰略,這是當代軟件開發者的宿命。