大概五年前,微軟發(fā)布了.NET Framework,這是Java/J2EE和.NET平臺上最流行的幾個“專家級”產(chǎn)品之一。從那以來,我一直在講Java/.NET的協(xié)調(diào)性。無論我在哪里講,都有一個出現(xiàn)頻率極高的問題(來自我的朋友,參會人員,咨詢客戶等等)。
問:說實話,我不會傳出去的。你最喜歡哪一個?是Java還是.NET?
我并不偏好哪一個,兩個我都同樣喜歡。說實話這個答案不太容易令人信服。所以我通常用得最多的回答是下面這個。
答:看情況。
我們的業(yè)界已經(jīng)被深深地分成了兩邊,核心問題是:“你使用哪種平臺?你是Java開發(fā)者,還是.NET開發(fā)者?”從這個問題的相關(guān)討論來看,有人可能會認(rèn)為這是目前最主要的話題,其中往往伴隨著激烈的爭吵和辯論。暫且不管傳統(tǒng)的“征用權(quán)”與“皇權(quán)侵略”的爭論,以及那些主流媒體認(rèn)為與伊拉克和東北非的動蕩同樣重要的各種文章。如果計算其中情感的力量,世界上最重要的問題莫過于你編程時主要使用Eclipse還是Visual Studio。
諷刺而有趣的是這些爭論毫無重點。Java和.NET雖然有些方面存在沖突,實際上它們是兩種截然不同的平臺,存在各自的優(yōu)點和缺點。兩種平臺都是從各自所在的社區(qū)和文化中開發(fā)(或產(chǎn)生)出來的,因此它們通常針對不同的問題,使用不同的方法和實現(xiàn)手段。
而且近年來它們本身已經(jīng)開始出現(xiàn)分歧。以前的各種會議上,我可以說,人們選擇Java或者.NET更多是出于文化因素,“任何你通過其中一個可以做到的事,都可以通過另一個在同樣的工作量下實現(xiàn)”?,F(xiàn)在不是這樣了。以前說.NET1.0/1.1與Java相當(dāng)是可以的,而現(xiàn)在它們已經(jīng)開始不同的發(fā)展方向,實現(xiàn)它們獨有的創(chuàng)新和用戶群的反饋。Java社區(qū)目前致力于各種語言與平臺之間的合作,比如說與微軟最新版本.NET3.0,兩個截然不同的平臺間進(jìn)行的標(biāo)準(zhǔn)統(tǒng)一。于是關(guān)于Java和.NET的問題開始有微妙的轉(zhuǎn)變,人們不再問“你喜歡哪個平臺?”,而開始問一個更有趣而且有力的問題:“我怎樣才能把兩個平臺結(jié)合使用?”
完全列出可用的將兩個豐富的平臺進(jìn)行整合的方法超出了本文的范圍。我們可以來看幾個比較吸引人的方式,并且在理念和代碼上體會一下。
關(guān)于Java/.NET的協(xié)調(diào)性,最常用的例子大概就是廣泛使用的WebService,通常使用Windows表示層編程框架(WPF)或WinForms界面,結(jié)合Windows分布式編程框架(WCF)將數(shù)據(jù)實際傳送到另一端以某種Java容器形式保存的Java WebService,可能是WebLogic,WebSphere,Spring,Tomcat,等等。搭建WebService的酸甜苦辣有許多文章進(jìn)行了描寫,所以在此不必多費筆墨。但如果將WebService作為CORBA或.NET遠(yuǎn)程控制(或者說分布式對象技術(shù))的擴(kuò)展,會大量消耗額外的工作和精力。使用恰當(dāng)?shù)姆?wù),能夠創(chuàng)建比希望換掉的分布式對象工具更松散的耦合,尤其是能夠更輕松地突破我們所討論的技術(shù)壁壘。WCF和JAX-WS的核心觀念都是“傳輸消息,而非對象”,只有表面層的一些API使它們看上去比較像RMI或.NET遠(yuǎn)程控制。因此在搭建WebService時可以利用它們良好的協(xié)調(diào)性。本方案最明顯的優(yōu)點是每種技術(shù)都集中于它所專長的部分。前端界面使用平臺獨有的技術(shù),因此可以發(fā)揮全部性能;而后端使用的開發(fā)平臺則因性能和可測量性著稱。
自從SQL Server 2005發(fā)布以來,一種新的消息處理方式誕生了,這就是SQLServer服務(wù)代理,用于搭建基于消息的通訊程序。這種方式基于SQLServer的數(shù)據(jù)引擎實現(xiàn)(服務(wù)代理中的隊列均為高效數(shù)據(jù)表,頂層以簡單的外殼包裝),并且具有足夠的強(qiáng)壯性,能夠用于事務(wù)型和有序傳輸保證。服務(wù)代理為開發(fā)人員提供強(qiáng)制消息平臺,尤其是在那些已經(jīng)有數(shù)據(jù)庫的數(shù)據(jù)中心里。然而使用Java訪問SQLServer服務(wù)代理和訪問其它JDBC數(shù)據(jù)庫同樣簡單。Java應(yīng)用程序,——無論是客戶端程序,還是服務(wù)器處理引擎,——都可以通過微軟SQLServer 2005 JDBC驅(qū)動(可以在MSDN上免費下載)訪問服務(wù)代理,或者向服務(wù)代理程序發(fā)送信息,以及必要的時候接收來自服務(wù)代理的信息。
在本示例中,一個虛擬的公寓大樓需要在網(wǎng)上生成維護(hù)人員的工作順序,以便住戶不必打電話要求辦公室來安排傳票(從而花費辦公室人員三倍的寶貴時間來填寫紙質(zhì)表格;事實上辦公室人員很討厭對住戶的要求視而不見)。
因此,解決方案提供者構(gòu)建了一個簡單而輕便的網(wǎng)絡(luò)系統(tǒng),其中只有兩個JSP頁面:一個供住戶將傳票放入服務(wù)中,另一個供維護(hù)人員收集傳票并瀏覽。系統(tǒng)的目的很簡單,第一個頁面收集傳票信息,包括問題描述,公寓本身,住戶姓名和電話等,然后將信息排入ServiceBroker的隊列中,等待維護(hù)部門訪問第二個JSP頁面來獲取待處理的任務(wù)列表。
至于實現(xiàn)方式,從Java的角度來說,使用ServiceBroker和使用其它以JDBC為驅(qū)動的數(shù)據(jù)庫并沒有很大區(qū)別。要把消息送入隊列中,只需要一個對SQL Server實例的JDBC調(diào)用,就像傳統(tǒng)方式寫一個INSERT或者UPDATE語句一樣:
獲取消息的方式更為直接,使用SQL Server的RECEIVE關(guān)鍵字:
或許會有許多人提出疑問,這里為何使用SQLServer服務(wù)代理,而不使用對Java更加友好的JMS實現(xiàn)方式,比如開源的ActiveMQ或商業(yè)的SonicMQ。要回答這個問題,可能會回到以往Java/.NET兼容性問題中常用的答案上:“我們這樣做是迫不得已?!备姓f服力的答案是:為了“會話”。ServiceBroker提供了JMS標(biāo)準(zhǔn)中前所未有的會話功能。與事務(wù)型消息傳遞相類似,會話表現(xiàn)為往返傳遞的一系列信息,每個會話都有唯一的標(biāo)識符。本質(zhì)上而言,這是連續(xù)RPC調(diào)用和獨立的單獨路徑信息的結(jié)合。它提供了消息通訊系統(tǒng)中通常難以具備的可靠性和健壯性。在我們上面的虛擬示例中,會話的使用有些隨意,它在長時間運行的商業(yè)流程中也同樣可以非常強(qiáng)大。上面代碼中的標(biāo)識符conversationId在每個ServiceBroker實例中是唯一的,標(biāo)識本次用戶交互中消息的集合(本例中只有一個)。
另一個可能出現(xiàn)的問題是為何使用JSP來編寫網(wǎng)頁界面,而不使用ASP.NET;對于非Windows平臺而言,這仍然是個“迫不得已”的選擇。但JSP有其獨到之處,就是用于生成美觀界面的豐富的工具和預(yù)編譯組件。如果我們討論所有的Java/Web space工具,比如Struts, Seam, WebWork, JSF, Google WebToolkit等等,都使Web開發(fā)體驗與傳統(tǒng)ASP.NET的拖放方式截然不同。(對不熟練的Web開發(fā)人員,拖放方式或許很適用,但熟練者都有自己喜歡的方式,并且覺得ASP.NET的設(shè)計與他們的方式相沖突。)關(guān)于SQL Server服務(wù)代理更詳細(xì)的討論,請見勃切明與蘇利文的《SQLServer 2005開發(fā)人員指南》。關(guān)于Servlet和JSP更詳細(xì)的討論,請見杰森?弗克納和凱文?瓊斯的《JavaServlet與JSP》。關(guān)于JDBC更詳細(xì)的討論,請見費舍爾、艾利斯和布魯斯的《JDBC教程與API參考,第三版》。
狂熱的開源分子聽到這一方案可能有些難以接受。毫無疑問,在過去10年中,微軟的Office提供了世界上最流行的辦公室生產(chǎn)效率軟件系列。世界上被安裝次數(shù)最多的軟件可能就是Office,其次是Windows本身。
近年來,Java社區(qū)在討論富客戶端程序,拋棄以往的點擊、等待、閱讀的網(wǎng)絡(luò)模式,尋求更具有交互性的用戶體驗。AJAX實現(xiàn)了其中的部分功能,代價是需要編寫大量額外的腳本代碼以應(yīng)對不同的瀏覽器或瀏覽器版本(而有些瀏覽器禁止使用AJAX)。Java社區(qū)中有人將Eclipse富客戶端平臺視為解決法寶,有人推崇JavaWebStart, 或者Adobe Flex等等。
最好的富客戶端應(yīng)該基于終端用戶機(jī)器上已經(jīng)安裝的軟件。因為Office是安裝范圍最廣的,尤其是在企業(yè)范圍內(nèi)的機(jī)器,何不利用Office的優(yōu)秀擴(kuò)展接口,將Office用作富客戶端,在后端使用Java?
為了出版Office對象模型和使用方法相關(guān)的書籍,文章,教程和參考文檔,我們不知道已經(jīng)砍伐了多少森林。算上.NET和未使用的COM,Office接口非常復(fù)雜,在此列舉也沒有意義。本文將集中于Office擴(kuò)展模型之一,智能標(biāo)簽,以及使用XML定義文件來識別Office文檔中詞匯(通常是在Excel和Word中使用,不過PowerPoint和Access也可以使用)并提供下拉菜單供用戶跳轉(zhuǎn)到某個網(wǎng)站的智能標(biāo)簽列表。
在這種情況下,虛擬環(huán)境很簡單:一家在線電子經(jīng)銷商發(fā)現(xiàn)他們的在線寵物商店非?;鸨ㄋ麄兘K于解決了通過與世界各地的寵物商店談判后水路郵遞寵物的問題),而他們使用SpringJPetStore范例編寫的首頁現(xiàn)在需要處理各種復(fù)雜的計算,遵守公司內(nèi)財務(wù)人員和市場人員提出的商業(yè)規(guī)則。簡單的訂單都留給首頁處理,但復(fù)雜一些的訂單將由銷售人員通過面談或電話完成。
復(fù)雜的計算法則需要復(fù)雜的處理語言來實現(xiàn),而這正是Excel的用武之地——財務(wù)人員和市場人員都可以在Excel中使用公式語言來自己編寫法則,——我們要做的下一步是將Excel中的數(shù)據(jù)表格顯示為Spring前端首頁。此時第一步只需要從Excel文檔中識別出訂單和產(chǎn)品號,然后顯示出智能標(biāo)簽將銷售人員指向Spring編寫的網(wǎng)站中準(zhǔn)確的頁面。(進(jìn)一步的改進(jìn)可以在保存數(shù)據(jù)表格時自動下訂單,或者在試圖銷售沒有庫存的寵物時彈出警告信息等。)
用簡單的XML文件實現(xiàn)這些,要比使用Java和.NET代碼更加實用。幸好URL天性靈活,智能列表標(biāo)簽不必介意URL所指向的網(wǎng)站其實是用Spring編寫的。如下所示的智能標(biāo)簽會每天刷新,隨時顯示出新的商品ID。(“看啊,孩子們,我們現(xiàn)在有雪貂的庫存!”)
簡單來說,我們需要建立兩個智能標(biāo)簽。一個用來識別產(chǎn)品ID(FL-DSH-01等等),另一個用來識別項目ID(EST-16, EST-17等等). 我們只需要在URL中使用ID值來替換{TEXT}占位符并訪問網(wǎng)站。這里的ID編碼很復(fù)雜,但
智能標(biāo)簽的能力遠(yuǎn)遠(yuǎn)超出這個簡單的例子所展現(xiàn)的。Visual Studio Tools for OfficeAPI可以讓.NET開發(fā)人員在所需要的智能標(biāo)簽后面編寫任意形式的代碼,所以在激活智能標(biāo)簽時向JPetStore引擎進(jìn)行遠(yuǎn)程調(diào)用(使用WebService調(diào)用或其它商業(yè)工具,例如JNBridge或者ZeroC’s ICE)來獲取當(dāng)前庫存量等操作也完全可以實現(xiàn)。
智能標(biāo)簽并不是Office整合能力的極限。文檔表格可以通過自定義為任何Java系統(tǒng)充當(dāng)用戶界面,Excel的公式語言可以通過自定義公式進(jìn)行擴(kuò)展(當(dāng)然可以通過本地JVM使用JavaAPI或者遠(yuǎn)程調(diào)用Java系統(tǒng)),等等。而且方式不止一種——必要的時候,Word和Excel都可以裝入EclipseRCP,或者說,任何一個COM自動對象都可以這樣使用,而Word和Excel本身的功能仍然完整保留。
當(dāng)然,以上并非全部可用方案,只是最近幾次討論和客戶會談中想到的一些。其它方案還有:
越來越多的開發(fā)人員開始意識到結(jié)合使用.NET和Java的優(yōu)勢,因此越來越多的方案將得到實施。Java和.NET社區(qū)都在進(jìn)行更多的創(chuàng)新,因此雙方都會更加開放而誠懇地考慮如何更好地解決客戶的問題。畢竟最后不論你喜歡哪種技術(shù),我們的目的都是一個:為客戶提供解決方案。
Ted Neward是Neward &Associate公司的主要負(fù)責(zé)人,該公司是致力于使用Java、.NET、XML及其它必要工具的企業(yè)系統(tǒng)的咨詢公司。他從1991年起開始使用C++,從1997年起開始使用Java,從2000年起開始使用.NET。他兼任PluralSight的.NET講師,獨立教授Java,在世界Java和.NET社區(qū)中的各種會議上發(fā)言,為MSDN、InfoQ和TheServerSide撰寫文章,并著有《果殼中的C#》,《SSCLI本質(zhì)》與《有效的企業(yè)級Java》等書籍。這些信息記錄于網(wǎng)站http://www.tedneward.com。
需要注意,本文的讀者通常對兩種技術(shù)中的一個比較熟悉,而不是都熟悉。因此,下面將列出兩種平臺的主要構(gòu)成。這里并不是要對每種組件進(jìn)行介紹,或者進(jìn)行詳細(xì)的列舉。讀者可以通過文末的參考文獻(xiàn)尋找更多信息。
Java:
.NET: