對象導論之Java與Internet(二)客戶端編程

客戶端編程
  Web最初的“服務器——瀏覽器”設計是爲了能夠提供交互性的內容,但是其交互性完全由服務器提供。服務器產生靜態頁面,提供給只能解釋並顯示他們的客戶端瀏覽器。基本的HTML(HyperText Markup Language,超文本標記語言)包含有簡單的數據收集機制:文本輸入框、複選框、單選框、列表和下拉式列表以及按鈕——它只能被編輯來實現復位表單上的數據或提交表單上的數據給服務器。這種提交動作通過所有的Web服務器都提供的通用網關接口(common gateway interface,CGI)傳遞。提交內容會告訴CGI應該如何處理它。最常見的動作就是運行一個在服務器中常被命名爲“cgi-bin”的目錄下的一個程序。(當點擊了網頁上的按鈕時,如果觀察瀏覽器窗口頂部的地址,有時可以看見“cgi-bin”的字樣混跡在一串k冗長和不知所云的字符中。)幾乎所有的語言都可以用來編寫這些程序,Perl已經成爲最常見的選擇,因爲它被設計用來處理文本,並且是解釋性語言,因此無論服務器的處理器和操作系統如何,它都適於安裝。然而,Python(www.Python.org)已對其產生了重大的衝擊,因爲它更強大且簡單。
  當今許多有影響力的網站完全構建於CGI之上的,實際上你幾乎可以通過CGI做任何事。然而,構建於CGI程序之上的網站可能會迅速變得過於複雜而難以維護,並同時產生響應時間過長的問題。CGI程序的響應時間依賴於所必須發送的數據量的大小,以及服務器和Internet的負載。(此外,啓動CGI程序也相當慢。)Web的最初設計者們並沒有預見到網絡帶寬被人們開發的各種應用迅速耗盡。例如,任何形式的動態圖形處理幾乎都不可能連貫地執行,因爲圖形交互格式的文件必須在服務端創建每一個圖形版本,併發送給客戶端。再比如,你肯定經歷過對Web輸入表單進行數據驗證的過程:你按下網頁上的提交按鈕;數據被髮送回服務器;服務器啓動一個CGI程序來檢查、發現錯誤,並將錯誤組裝成爲一個HTML頁面,然後將這個頁面發回給你;之後你必須回退一個頁面,然後重新再試。這個過程不僅很慢,而且不太優雅。
  問題的解決方法就是客戶端編程。大多數運行Web瀏覽器的機器都是能夠執行大型任務的強有力的引擎。在使用原始的靜態HTML方式的情況下,它們只是閒在那裏,等着服務器送來下一個頁面。客戶端編程意味着Web瀏覽器能用來執行任何它可以完成的工作,使得返回給用戶的結果更加迅捷,而且使得你的網站更加具有交互性。
  客戶端編程的問題是:它與通常意義上的編程十分不同,參數幾乎相同,而平臺卻不相同。Web瀏覽器就像一個功能受限的操作系統。最終,你仍然必須編些程序,而且還得處理那些令人頭暈眼花的成堆的問題,並以客戶端編程的方式來產生解決方案。本節剩下的部分對客戶端編程的問題和方法作一概述。
  1.插件
  客戶端編程所邁出的最重要的一步就是插件(plug-in)的開發。通過這種方式,程序員可以下載一段代碼,並將其插入到瀏覽器中適當的位置,以此來爲瀏覽器添加新功能。它告訴瀏覽器:從現在開始,你可以採取這個新行動了(只需要下載一次插件即可)。某些更快更強大的行爲都是通過插件添加到服務器中的。但是編寫插件並不是件輕鬆的事,也不是構建某特定網站的過程中所要做的事情。插件對於客戶端編程的價值在於:它允許專家級的程序員不需要經過瀏覽去生產廠家的許可,就可以開發某種語言擴展,並將它們添加到服務器中。因此,插件提供了一個“後門”,使得可以創建新的客戶端編程語言(但是並不是所有的客戶端編程語言都是以插件的形式實現的)。
  2.腳本語言
  插件引發了瀏覽器腳本語言(scripting language)的開發。通過使用某種腳本語言,你可以將客戶端程序的源代碼直接嵌入到HTML頁面中,解釋這種語言的插件在HTML頁面被顯示時自動激活。腳本語言先天就相當易於理解,因爲它們只是作爲HTML頁面一部分的簡單文本,當服務器收到要獲取該頁面的請求是,它們可以被快速加載。此方法的缺點是代碼會暴露給任何人去瀏覽(或竊取)。但是,通常不會使用腳本語言去做相當複雜的事情,所以這個缺點並不太嚴重。
  如果你期望有一種腳本語言在Web瀏覽器不需要任何插件的情況下就可以得到支持,那它非JavaScript莫屬(它與Java之間只存在表面上的相似,要想使用它,你必須在額外的學習曲線上攀爬。它之所以這樣被命名只是因爲想趕上Java潮流)。遺憾的是,大多數Web瀏覽器最初都是以彼此相異的方式來實現對JavaScript的支持的,正種差異甚至存在於同一種瀏覽器的不同版本之間。以ECMAScript的形式實現的JavaScript的標準化有助於此問題的解決,但是不同的瀏覽器爲了跟上這一標準化趨勢已經花費了相當長的時間(並且這種努力由於微軟一直在推進它自己的VBScript形式的標準化日程而顯得無所幫助,VBScript與JavaScript之間也存在着曖昧的相似性)。通常,你必須以JavaScript的某種最小公分母形式來編程,以使得你的程序可以在所有的瀏覽器上運行。JavaScript的錯誤處理的調試只能一團糟來形容。作爲其使用艱難的證據,我們可以看到知道最近纔有人創建了真正複雜的JavaScript腳本片段,並且編寫這樣的腳本需要超然的奉獻精神和超高的專業技巧。
  這也表明,在Web瀏覽器內部使用的腳本語言實際上總是被用來解決特定類型的問題,主要用來創建更豐富、更具有交互性的圖形化用戶界面。但是,腳本語言可以解決客戶端編程中所遇到的百分之八十的問題。你的問題可能正好在這百分之八十的範圍之內,由於腳本語言提供了更容易、更快捷的開發方式,因此你應該在考慮諸如Java這樣的更復雜的解決方案之前,先考慮腳本語言。
  3.Java
  如果腳本語言可以解決客戶編程百分之八十的問題的話,那麼剩下的百分之二十(那纔是真正難啃的硬骨頭)又該怎麼辦?Java是處理它們最流行的解決方案。Java不僅是一種功能強大的、安全的、跨平臺的、國際化的編程語言,而且它還在不斷的被擴展,以提供更多的語言功能和類庫,能夠優雅地處理在傳統編程語言中很難解決的問題,例如併發、數據庫訪問、網絡編程和分佈式計算。Java是通過applet以及使用Java Web Start來進行客戶端編程的。
  applet是隻在Web瀏覽器中運行的小程序,它是作爲網頁的一部分而自動下載的(就像網頁中的圖片被自動下載一樣)。當applet被激活時,它便開始執行一個程序。這正是它優雅之處:它提供一種分發軟件的方法,一旦用戶需要客戶端軟件時,就自動從服務器把客戶端軟件分發給客戶。用戶獲取最新版本的客戶端軟件時不會產生錯誤,而且也不需要很麻煩的重新安裝過程。Java的種種設計方式,使得程序員只需創建單一的程序,而只要一臺計算機有瀏覽器,且瀏覽器具有內置的Java解釋器(大多數的機器都如此),那麼這個程序就可以自動在這臺計算機上運行。由於Java是一種成熟的編程語言,所以在提出對服務器的請求之前和之後,可以在客戶端儘可能多地做些事情。例如,不必跨網絡地發送一張請求表單來檢查自己是否填寫了錯誤的日期或其他參數,客戶端計算機就可以快速標出錯誤數據,而不用等待服務器做出標記並給你傳回圖片。這不僅立即就獲取了高速度和快速的響應能力,而且也降低了網絡流量和服務器負載,從而不會使整個Internet的速度都慢了下來。
  4.備選方案
  老實說,Java applet沒有達到當初它所吹噓的境界。當Java首度出現時,似乎大家最歡喜鼓舞的莫過於applet了,因爲它們最終將解決嚴峻的客戶端可編程性問題,從而提高基於互聯網的應用的可響應性,同時降低它們對帶寬的需求。人們展望到了大量的可能性。
  實際上,你可以發現在Web上確實存在一些非常靈巧的applet,但是壓倒性的向applet的遷移卻始終未發生。這其實最大的問題可能在於安裝Java運行時環境(JRE)所必需的10MB帶寬對於一般的用戶來說過於恐怖了,而微軟沒有選擇在IE中包含JRE這一事實也許就此已經封殺了applet的命運。無論怎樣,Java applet始終沒有得到大規模應用。
  儘管如此,applet和Java Web Start應用在某些情況下仍舊很有價值。無論何時,只要你想控制用戶的機器,例如在一個公司的內部,使用這些技術來發布和更新客戶端應用就顯得非常恰當,並且這可以節省大量的時間、人力和財力,特別是你需要頻繁地更新的時候。
  在“圖形化用戶界面”中,我們將看到一種折中的新技術,Macromedia的Flex,它允許你創建基於Flash的與applet相當的應用。因爲Flash Player在超過98%的Web瀏覽器上都可用(包含Windows,Linux和Mac操作系統上的瀏覽器),因此它被認爲是事實上已被接受的標準。安裝和更新Flash Player都十分快捷。ActionScript語言是基於ECMAScript的,因此我們對它應該很熟悉,但是Flex使得我們在編程是無需擔心瀏覽器相關性,因此,它遠比JavaScript要吸引人得多。對於客戶端編程而言,這是一種值得考慮的備選方案。
  5…NET和C#
  曾幾何時,Java applet的主要競爭對手是微軟的ActiveX——儘管它要求客戶端必須運行Windows平臺。從那以後,微軟以.NET平臺和C#編程語言的形式推出了與Java全面競爭的對手。.NET平臺大致相當於Java虛擬機(JVM,即執行Java程序的軟件平臺)和Java類庫,而C# 毫無疑問與Java有類似之處。這當然是微軟在編程語言與編程環境這塊競技場上所做出的最出色的成果。當然,它們有相當大的有利條件:它們可以看得到Java在什麼方面做得好,在什麼方面做得還不夠好,然後基於此去構建,並要具備Java不具備的優點。這是自從Java出現以來,Java所碰到的真正的競爭。因此,Sun的Java設計者們已經認真仔細地去研究了C#,以及爲什麼程序員們可能會轉而使用它,然後通過在Java SES中對Java做出的重大改進而做出了迴應。
  目前,.NET主要受攻擊的地方和人們所關心的最主要的問題就是,微軟是否會允許將它完全移植到其他平臺上。微軟宣稱這麼做沒有問題,而且Mono項目(www.go-mono.com)已經有了一個在Linux上運行的.NET的部分實現;但是,在該實現完成及微軟不會排斥其中的任何部分之前,.NET作爲一種跨平臺的解決方案仍舊是一場高風險的賭博。
  6.Internet與Intranet
  Web是最常用的解決客戶/服務器問題的方案,因此,即便是解決這個問題的一個子集,特別是公司內部的典型的客戶/服務器問題,也一樣可以使用這項技術。如果採用傳統的客戶/服務器方式,可能會遇到客戶端計算機有多種型號的問題,也可能會遇到安裝新的客戶端軟件的麻煩,而他們都可以很方便地通過Web瀏覽器和客戶端編程得以解決。當Web技術僅限用於特定公司的信息網絡時,它就被稱爲Intranet(企業內部網)。Intranet比Internet提供了更高的安全性,因爲可以物理地控制對公司內部服務器的訪問。從培訓的角度看,似乎一旦人們理解了瀏覽器的基本概念後,對他們來說,處理網頁和apptlet的外觀差異就會容易得多,因此對新型系統的學習曲線也就減緩了。
  安全問題把我們帶到了一個領域,這似乎是在客戶端編程世界自動形成的。如果程序運行在Internet之上,那麼就不可能知道它將運行在什麼樣的平臺之上,因此,要格外小心,不要傳播bug的代碼。你需要跨平臺的、安全的語言,就像腳本語言和Java。
  如果程序運行在Intranet上,那麼可能會受到不同的限制。企業內所有的機器都採用Intel/Windows平臺並不是什麼稀奇的事。在Intranet上,你可以對你自己的代碼質量負責,並且在發現bug之後可以修復它們。此外,你可能已經有了以前使用更傳統的客戶/服務器方式編寫的遺留代碼,因此,你必須在每一次升級時都要物理地重裝客戶端程序。在安裝升級程序時所浪費的時間是遷移到瀏覽器方式上的最主要的原因,因爲在瀏覽器方式下,升級是透明的、自動地(Java Web Start也是解決此問題的方式之一)。如果你身處這樣的Intranet之中,那麼最有意義的方式就是選擇一條能夠使用現有代碼庫的最短的捷徑,而不是用一種新語言重新編寫你的代碼。
  當面對各種令人眼花繚亂的解決客戶端編程問題的方案時,最好的方法就是進行性價比分析。認真考慮問題的各種限制,然後思考哪種解決方案可以成爲最短的捷徑。既然客戶端編程仍然需要編程,那麼針對自己的特殊應用選取最快的開發方式總是最好的做法。爲那些在程序開發中不可避免的問題提早作準備是一種積極的態度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章