以下內(nèi)容含腳本,或可能導(dǎo)致頁(yè)面不正常的代碼 |
---|
說(shuō)明:上面顯示的是代碼內(nèi)容。您可以先檢查過(guò)代碼沒(méi)問(wèn)題,或修改之后再運(yùn)行. |
以下內(nèi)容含腳本,或可能導(dǎo)致頁(yè)面不正常的代碼 |
---|
說(shuō)明:上面顯示的是代碼內(nèi)容。您可以先檢查過(guò)代碼沒(méi)問(wèn)題,或修改之后再運(yùn)行. |
(2)主要Java開(kāi)源軟件的種類(lèi)
JavaWeb容器: Tomcat、Resin
EJB容器: JBoss
框架: Java Web框架(Struts)、業(yè)務(wù)邏輯層框架(Spring)
持久化層: DAO、ORM映射工具(如Hibernate、OJB)
工程管理工具:ANT、Eclipse
日志輸出工具: Log4J
JavaWeb服務(wù)工具:Apache Axis
促成Java世界如此絢麗多姿的基本動(dòng)力在于以下核心思想:
接口與實(shí)現(xiàn)
不同的軟件系統(tǒng)之間通過(guò)接口來(lái)交互。軟件系統(tǒng)只對(duì)外公開(kāi)接口,封裝實(shí)現(xiàn)細(xì)節(jié)。接口描述了軟件系統(tǒng)具備的功能,也就是指定軟件系統(tǒng)能夠做什么,但是沒(méi)有指明怎么去做。接口具有三大作用:
(1)對(duì)于接口制訂者:SUN公司通過(guò)定義接口,來(lái)制定新的軟件系統(tǒng)的規(guī)范,例如Servlet規(guī)范、EJB規(guī)范和JDO規(guī)范,這些規(guī)范主要以接口的形式描述了軟件系統(tǒng)必須具備的功能。通過(guò)制定規(guī)范,SUN公司指引著Java技術(shù)的發(fā)展方向,同時(shí)給接口的實(shí)現(xiàn)者提供了自由發(fā)揮的廣闊空間。
(2)對(duì)于接口實(shí)現(xiàn)者:接口實(shí)現(xiàn)者以特定的方式實(shí)現(xiàn)標(biāo)準(zhǔn)的規(guī)范。例如一些開(kāi)放源代碼軟件,如Tomcat和Resin分別以不同的實(shí)現(xiàn)方式,實(shí)現(xiàn)了標(biāo)準(zhǔn)的Servlet規(guī)范。同一個(gè)接口允許有多種實(shí)現(xiàn),使得Java領(lǐng)域保持著百花齊放、百家爭(zhēng)鳴的良好勢(shì)頭,
(3)對(duì)于接口調(diào)用者:接口調(diào)用者的程序具有良好的可移植性。以JavaWeb應(yīng)用為例,由于Tomcat和Resin遵守同樣的規(guī)范,因此用戶開(kāi)發(fā)的JavaWeb應(yīng)用能夠順利的從Tomcat容器移植到Resin容器中。
封裝與抽象
封裝指的是在一個(gè)大系統(tǒng)中包含一個(gè)小系統(tǒng),大系統(tǒng)是建立在已有小系統(tǒng)的基礎(chǔ)上的更為復(fù)雜、功能更強(qiáng)大的系統(tǒng)。例如,Hibernate對(duì)JDBC API進(jìn)行了封裝,在Hibernate內(nèi)部依賴JDBC API來(lái)操縱數(shù)據(jù)庫(kù),但是Hibernate API比JDBC API具有更強(qiáng)大的功能,例如JDBC API只具有連接和操縱數(shù)據(jù)庫(kù)的功能,而Hibernate不僅具備這一功能,還具有對(duì)象-關(guān)系映射的功能。
抽象是指從已經(jīng)存在的具有相似功能、但不同接口的系統(tǒng)中抽取共性,提煉出統(tǒng)一的接口。例如,Hibernate Transaction API是對(duì)JDBC
Transaction API和Java Transaction API(JTA)的抽象。
繼承與擴(kuò)展
繼承與擴(kuò)展是一對(duì)孿生兄弟,當(dāng)兩個(gè)類(lèi)之間存在繼承關(guān)系,那么必定也存在擴(kuò)展關(guān)系。繼承的優(yōu)點(diǎn)在于提高代碼的可重用性,子類(lèi)會(huì)繼承父類(lèi)的所有public和protected類(lèi)型的屬性和方法,在子類(lèi)的程序代碼中,無(wú)需重復(fù)定義這些屬性和方法。擴(kuò)展的優(yōu)點(diǎn)在于使軟件應(yīng)用具有可伸縮性,能夠在已有功能的基礎(chǔ)上擴(kuò)展新的功能。
Struts框架充分運(yùn)用了擴(kuò)展思想。Struts框架中的許多類(lèi)都是供應(yīng)用程序擴(kuò)展的,其中最主要的一個(gè)是Action類(lèi),在Action類(lèi)中已經(jīng)定義了一些通用的方法,采用Struts框架的JavaWeb應(yīng)用將擴(kuò)展Action類(lèi),創(chuàng)建負(fù)責(zé)特定流程或業(yè)務(wù)的客戶化的Action類(lèi)。
對(duì)象的生命周期
當(dāng)一個(gè)對(duì)象通過(guò)new語(yǔ)句創(chuàng)建后,它就會(huì)擁有一塊固定的內(nèi)存空間,如果沒(méi)有任何變量引用它,它就會(huì)結(jié)束生命周期,它占用的內(nèi)存空間隨時(shí)可能被JVM的垃圾回收器回收。
應(yīng)用程序如何管理對(duì)象的生命周期呢?目前比較流行的做法是把對(duì)象存放在一個(gè)“范圍”內(nèi)。例如在JavaWeb應(yīng)用中,JavaBean可以存放在request、session或application范圍內(nèi)。每個(gè)范圍對(duì)應(yīng)一個(gè)對(duì)象,例如request范圍對(duì)應(yīng)HttpServletRequest對(duì)象,session范圍對(duì)應(yīng)HttpSession對(duì)象,application范圍對(duì)應(yīng)ServletContext對(duì)象。把一個(gè)JavaBean存放在request范圍內(nèi),實(shí)質(zhì)上是在HttpServletRequest對(duì)象的一個(gè)集合屬性中加入這個(gè)JavaBean的引用,這個(gè)集合屬性也被稱為HttpServletRequest對(duì)象的緩存。
把一個(gè)JavaBean存放在request范圍內(nèi),等價(jià)于以下兩種說(shuō)法:
把一個(gè)JavaBean加入到HttpServletRequest對(duì)象的緩存中
把一個(gè)JavaBean和HttpServletRequest對(duì)象關(guān)聯(lián)
當(dāng)JavaBean位于request范圍內(nèi),這個(gè)JavaBean的生命周期依賴于HttpServletRequest對(duì)象的生命周期,當(dāng)HttpServletRequest對(duì)象結(jié)束生命周期,并且這個(gè)JavaBean也不被應(yīng)用程序中的其他變量引用,那么它就會(huì)結(jié)束生命周期。
那么HttpServletRequest對(duì)象本身的生命周期由誰(shuí)管理呢?這是由JavaWeb容器(也稱Servlet容器)來(lái)管理的。對(duì)于每個(gè)HTTP請(qǐng)求,JavaWeb容器會(huì)自動(dòng)創(chuàng)建一個(gè)HttpServletRequest對(duì)象,當(dāng)HTTP請(qǐng)求的響應(yīng)完畢,JavaWeb容器就會(huì)結(jié)束這個(gè)對(duì)象的生命周期。同理,當(dāng)每個(gè)HTTP會(huì)話開(kāi)始,JavaWeb容器會(huì)自動(dòng)創(chuàng)建一個(gè)HttpSession對(duì)象,當(dāng)這個(gè)會(huì)話結(jié)束,JavaWeb容器就會(huì)結(jié)束這個(gè)對(duì)象的生命周期;當(dāng)每個(gè)JavaWeb應(yīng)用啟動(dòng)時(shí),JavaWeb容器會(huì)自動(dòng)創(chuàng)建一個(gè)ServletContext對(duì)象,當(dāng)這個(gè)應(yīng)用被關(guān)閉,JavaWeb容器就會(huì)結(jié)束這個(gè)對(duì)象的生命周期。
在Hibernate中,在net.sf.hibernate.Session范圍內(nèi)加入一個(gè)持久化對(duì)象,實(shí)質(zhì)上是在Session對(duì)象的集合屬性中加入這個(gè)持久化對(duì)象的引用。以下幾種說(shuō)法是等價(jià)的:
在Session范圍內(nèi)加入一個(gè)持久化對(duì)象
在Session的緩存中加入一個(gè)持久化對(duì)象
把一個(gè)持久化對(duì)象與Session關(guān)聯(lián)
值得注意的是,Hibernate的Session不僅能管理緩存中持久化對(duì)象的生命周期,還會(huì)負(fù)責(zé)按照持久化對(duì)象的狀態(tài)的變化,來(lái)同步更新數(shù)據(jù)庫(kù)。
集成開(kāi)源軟件的基本步驟
在開(kāi)發(fā)Java應(yīng)用時(shí),為了提高開(kāi)發(fā)效率,縮短開(kāi)發(fā)周期,常常需要集成第三方提供的Java軟件,如ORM映射工具Hibernate、MVC框架Struts、日志工具Log4J和Web服務(wù)軟件Apache
AXIS等。在自己的應(yīng)用中集成這些第三方軟件時(shí),大體步驟都很相似。
(1) 把它們的JAR文件拷貝到classpath中。
(2) 創(chuàng)建它們的配置文件(XML格式的文件或者Java屬性文件),這些配置文件通常也位于classpath中。
(3) 在程序中訪問(wèn)它們的接口。
接口與配置文件,是軟件系統(tǒng)對(duì)外公開(kāi)的兩個(gè)主要窗口。無(wú)論是Tomcat、Struts還是Hibernate,都離不開(kāi)配置文件,與編寫(xiě)程序代碼相比,配置文件能提高軟件的可維護(hù)性,更加靈活的適應(yīng)用戶變化的需求,但是,配置文件不擅長(zhǎng)表達(dá)非常復(fù)雜的邏輯,在這種情況下,必須求助于程序代碼。作為軟件使用者,如果僅僅想快速掌握一個(gè)新的Java軟件的使用方法,而不打算深入了解軟件內(nèi)在原理和結(jié)構(gòu),無(wú)非就是了解它的接口以及配置文件的使用方法。當(dāng)然,如果想對(duì)軟件的運(yùn)用達(dá)到得心應(yīng)手的地步,還應(yīng)該了解軟件本身的實(shí)現(xiàn)原理和結(jié)構(gòu),而這些軟件無(wú)非就是通過(guò)抽象、封裝和實(shí)現(xiàn)等手段,從簡(jiǎn)單的小系統(tǒng)出發(fā),構(gòu)造出更加復(fù)雜,但是對(duì)外有著簡(jiǎn)潔統(tǒng)一的接口的大系統(tǒng)
下面為避免混淆,在文中凡未加特殊說(shuō)明的Java,統(tǒng)指桌面Java而言。
一、 問(wèn)題提出
*常用的解釋性Java(Java Applet)的執(zhí)行速度慢,不適于嵌入式的應(yīng)用。
*Java要求過(guò)大的內(nèi)存。
*嵌入式設(shè)備要求操作硬件。因Java廢棄了C語(yǔ)言所使用的指針,且在Web環(huán)境下使用了Java虛擬機(jī)(JVM),使Java無(wú)力直接甚至間接地用指針操作硬件。
*Java使用一些自動(dòng)功能會(huì)引起執(zhí)行時(shí)間的不確定性,成為嵌入式的大忌。如垃圾自動(dòng)收集器。本是對(duì)于C的重大改進(jìn),但卻因程序自動(dòng)地回收垃圾,從而引入了實(shí)時(shí)的時(shí)間不確定性。
二、解決方案
使用AOT編譯器
為解決解釋性Java(Java Applet)執(zhí)行速度過(guò)慢的問(wèn)題,發(fā)展了AOT(ahead-of-time)編譯器。大家喜歡在Internet上使用Java的一個(gè)原因是其字節(jié)碼具有跨平臺(tái)性,即同一Java代碼可以運(yùn)行于PC、Mac、Solaris,甚至于主機(jī)之上。為此,在英文叫它WORA(寫(xiě)一次即可通行于任意機(jī))。這是因?yàn)槊恳徊僮飨到y(tǒng)平臺(tái)上都有符合自己機(jī)型的專用Java虛擬機(jī)(JVM),由它對(duì)字節(jié)碼進(jìn)行解釋運(yùn)行。因?yàn)榻忉尦绦蛐柘缺唤忉屧俦粓?zhí)行,多了解釋環(huán)節(jié),延誤數(shù)秒鐘時(shí)間。如果是撥打電話,這個(gè)時(shí)間足以令人生厭。現(xiàn)在使用AOT(ahead-of-time)超前編譯器,提前將解釋碼轉(zhuǎn)換為本平臺(tái)所用的并經(jīng)優(yōu)化過(guò)的二進(jìn)制碼,速度提高很多。現(xiàn)有Cygnus公司聲稱,它開(kāi)發(fā)的AOT編譯器執(zhí)行速度是原解釋程序的8倍。NewMonics說(shuō)它的 QuickPERC編譯器是原解釋程序的20倍。當(dāng)然,AOT編譯器也有不足,就是他犧牲了Java的WORA。
減少內(nèi)存的占用
所有的面向?qū)ο笳Z(yǔ)言,比C及匯編語(yǔ)言點(diǎn)用內(nèi)存都多。這個(gè)問(wèn)題對(duì)于桌面系統(tǒng)早已不再是考慮的因素了,如服務(wù)器平均占用數(shù)GB的內(nèi)存已司空見(jiàn)慣。但是,對(duì)于嵌入式系統(tǒng)卻不能不考慮。用Java開(kāi)發(fā)的信息家電產(chǎn)品可能需要把內(nèi)存限制到512KB以下。如果嵌入式系統(tǒng)使用的是規(guī)模為1MB的核心類(lèi)庫(kù),那就是說(shuō),一句代碼尚未寫(xiě),內(nèi)存早就不夠用了。
為此,需要把用不到的類(lèi)、類(lèi)方法和代統(tǒng)統(tǒng)從程序中剔除。(AOT超前編譯器可以幫助解決這個(gè)問(wèn)題。)再就是自己開(kāi)發(fā)本平臺(tái)專用的,既短小高效、又符合Java API標(biāo)準(zhǔn)的Java核心類(lèi)庫(kù)。
開(kāi)發(fā)能混合編程的IDE
一般認(rèn)為,用C語(yǔ)言寫(xiě)的程序,指鍺使用不當(dāng)引起的缺陷占總?cè)毕莸?0%左右。Java語(yǔ)言,出于安全的考慮,才廢棄了使用指針。但是,指針卻能夠最直接地訪問(wèn)到存儲(chǔ)器和真實(shí)的硬件。現(xiàn)在,為在嵌入式Java中能夠訪問(wèn)到硬件,不得不改用本地接口,即從嵌入式Java中利用能夠訪問(wèn)到硬件的C語(yǔ)言函數(shù)來(lái)實(shí)行交叉編程。這就意味著增加了復(fù)雜性。開(kāi)發(fā)人員需要具備多語(yǔ)言以及多層次的混合編程和混合調(diào)試的能力。發(fā)展多語(yǔ)言多層次混合編程的IDE,無(wú)疑十分有助于一般開(kāi)發(fā)人員完成這一相當(dāng)復(fù)雜的課題。Metrowerks的CodeWorrior和IBM的VisualAge就是新開(kāi)發(fā)的基于J2ME的這樣的IDE。
克服時(shí)間的不確定性
Java 最主要的問(wèn)題是時(shí)間不確定性,主要來(lái)源于存儲(chǔ)器殘?jiān)淖詣?dòng)收集再生器。這種垃圾收集再生器工作的時(shí)候,自動(dòng)地決定何時(shí)停下其他程序的執(zhí)行,再根據(jù)當(dāng)時(shí)殘?jiān)膶?shí)際情況或長(zhǎng)或短地完成任務(wù)。所以,它嚴(yán)重地干擾實(shí)時(shí)應(yīng)用所要求的時(shí)間確定性。為解決這一問(wèn)題,不同公司采用不同的方法和垃圾收集的算法。 NewMonics的Real Time Executives和Windriver的FastJ都是保證絕對(duì)的確定時(shí)間,Sun公司用不同的辦法但也保證具有實(shí)時(shí)的確定性。采用不同的編程技巧,譬如使用類(lèi)型確定的線程局部存儲(chǔ),也可以避免因垃圾收集引發(fā)的沖突。
需保持跨平臺(tái)的必要
AOT 編譯器生成的Java代碼喪失了Java在其他操作平臺(tái)上的執(zhí)行能力。要想把Java的源代碼再向其他平臺(tái)移植,需要附加很大的勞動(dòng)。面向?qū)ο蟮囊粋(gè)基本設(shè)計(jì)原理就是只要保持接品不變,那么,與接口交談的代碼在移植時(shí)就不受影響。所謂高級(jí)邏輯接口的隔離手法,事實(shí)上,就是將平臺(tái)敏感的內(nèi)容同移值無(wú)關(guān)的代碼分離開(kāi)來(lái),并且分別提供同樣功能的平臺(tái)敏感程序。現(xiàn)在,針對(duì)嵌入式Java,目前還沒(méi)有人做這項(xiàng)工作。
三、實(shí)際應(yīng)用
Java是良好的嵌入式編程語(yǔ)言嗎?
還不能這么說(shuō),至少現(xiàn)在是這樣。因?yàn)樵谇度胧较到y(tǒng)中,Java如何應(yīng)用要看具體情況而定。對(duì)于需要管理中斷來(lái)完成重要任務(wù)的應(yīng)用系統(tǒng),就不宜于選用Java 進(jìn)行開(kāi)發(fā),譬如引導(dǎo)登外星的飛行器系統(tǒng)就是這樣。對(duì)于要求輕型、高效、任務(wù)重要、時(shí)間確定性要求極高的系統(tǒng),也是只能局限于使用C語(yǔ)言和匯編。比如,點(diǎn)燃登陸外星的制動(dòng)火箭系統(tǒng),定時(shí)通過(guò)串行口獲取關(guān)鍵信息一邊做出決定的系統(tǒng),定時(shí)報(bào)告航天器方位的系統(tǒng)等都不能使用Java。但是,需要不斷與他人通信聯(lián)系,以便對(duì)貨運(yùn)進(jìn)行有效管理的手持系統(tǒng),又最適合使用Java編程。因?yàn)椋劝l(fā)揚(yáng)了Java Applet固有的跨平臺(tái)應(yīng)用地Web環(huán)境的特點(diǎn),又能充分利用服務(wù)器端的現(xiàn)成軟件。
使用Java有時(shí)也并不完全取決于技術(shù)
立足于經(jīng)濟(jì)上的考慮,比單獨(dú)的技術(shù)考慮更為重要。譬如,對(duì)于服務(wù)器,為了支持使用Java,寧愿多花費(fèi)數(shù)千元擴(kuò)大存儲(chǔ)器是正確的。因?yàn)椋瑥耐度?產(chǎn)出的分析也得出同樣的結(jié)論。又如手機(jī),若為支持使用Java,哪性僅只需要多花一元錢(qián)去擴(kuò)大存儲(chǔ)器也是不可行的。因?yàn)椋謾C(jī)的生產(chǎn)是以行百萬(wàn)件的產(chǎn)量來(lái)考慮的,多花一元線,就意味著多花千百萬(wàn)元,諾大的數(shù)字遠(yuǎn)比技術(shù)的先進(jìn)更為重要,是顯而易見(jiàn)的。
實(shí)施嵌入式Java時(shí)需注意
Java 用于嵌入式還是瓣生事物,需要探路前進(jìn),摸著石頭過(guò)河,忌冒進(jìn)和全面開(kāi)花。應(yīng)試探性地從使用現(xiàn)成的嵌入式J2ME開(kāi)始,在它的通用性的開(kāi)發(fā)環(huán)境下運(yùn)行本平臺(tái)的字節(jié)碼。盡可能地順著J2MME向前走,盡可能地順著J2ME向前走,盡可能地走得遠(yuǎn)一點(diǎn),只有在遇到特殊問(wèn)題時(shí)才導(dǎo)求新的解決辦法。新方法的采用并不一定能夠解決問(wèn)題,比如,AOT或半自動(dòng)的垃圾收集器等可能并沒(méi)有解決你的問(wèn)題,也勿驚慌,要總結(jié)經(jīng)驗(yàn)做出評(píng)價(jià),繼續(xù)前進(jìn),使嵌入式Java日罄完善。
要重視IDE的選用,好的IDE絕對(duì)是良好的助手。否則,你是單槍匹馬,披荊斬棘,艱苦良多。
]]>軟件是有生命的,這可能是老調(diào)重彈了,但是因?yàn)樗玛P(guān)分層架構(gòu)的原由,反復(fù)強(qiáng)調(diào)都不過(guò)分。
一個(gè)有生命的軟件首先必須有一個(gè)靈活可擴(kuò)展的基礎(chǔ)架構(gòu),其次才是完整的功能。
目前很多人對(duì)軟件的思想還是焦點(diǎn)落在后者:完整的功能,覺(jué)得一個(gè)軟件功能越完整越好,其實(shí)關(guān)鍵還是架構(gòu)的靈活性,就是前者,基礎(chǔ)架構(gòu)好,功能添加只是時(shí)間和工作量問(wèn)題,但是如果架構(gòu)不好,功能再完整,也不可能包括未來(lái)所有功能,軟件是有生命的,在未來(lái)成長(zhǎng)時(shí),更多功能需要加入,但是因?yàn)榛A(chǔ)架構(gòu)不靈活不能方便加入,死路一條。
正因?yàn)槠胀ㄈ藢?duì)軟件存在短視誤區(qū),對(duì)功能追求高于基礎(chǔ)架構(gòu),很多吃了虧的老程序員就此離開(kāi)軟件行業(yè),帶走寶貴的失敗經(jīng)驗(yàn),新的盲目的年輕程序員還是使用老的思維往前沖。其實(shí)很多國(guó)外免費(fèi)開(kāi)源框架如ofbiz compiere和slide也存在這方面陷阱,貌似非常符合胃口,其實(shí)類(lèi)似國(guó)內(nèi)那些幾百元的盜版軟件,擴(kuò)展性以及持續(xù)發(fā)展性嚴(yán)重不足。
那么選擇現(xiàn)在一些流行的框架如Hibernate、Spring/Jdonframework是否就表示基礎(chǔ)架構(gòu)打好了呢?其實(shí)還不盡然,關(guān)鍵還是取決于你如何使用這些框架來(lái)搭建你的業(yè)務(wù)系統(tǒng)。
存儲(chǔ)過(guò)程和復(fù)雜SQL語(yǔ)句的陷阱
首先談?wù)劥鎯?chǔ)過(guò)程使用的誤區(qū),使用存儲(chǔ)過(guò)程架構(gòu)的人以為可以解決性能問(wèn)題,其實(shí)它正是導(dǎo)致性能問(wèn)題的罪魁禍?zhǔn)字唬騻(gè)比喻:如果一個(gè)人頻臨死亡,打一針可以讓其延長(zhǎng)半年,但是打了這針,其他所有醫(yī)療方案就全部失效,請(qǐng)問(wèn)你會(huì)使用這種短視方案嗎?
為什么這樣說(shuō)呢?如果存儲(chǔ)過(guò)程都封裝了業(yè)務(wù)過(guò)程,那么運(yùn)行負(fù)載都集中在數(shù)據(jù)庫(kù)端,要中間J2EE應(yīng)用服務(wù)器干什么?要中間服務(wù)器的分布式計(jì)算和集群能力做什么?只能回到過(guò)去集中式數(shù)據(jù)庫(kù)主機(jī)時(shí)代。現(xiàn)在軟件都是面向互聯(lián)網(wǎng)的,不象過(guò)去那樣局限在一個(gè)小局域網(wǎng),多用戶并發(fā)訪問(wèn)量都是無(wú)法確定和衡量,依靠一臺(tái)數(shù)據(jù)庫(kù)主機(jī)顯然是不能夠承受這樣惡劣的用戶訪問(wèn)環(huán)境的。(當(dāng)然搞數(shù)據(jù)庫(kù)集群也只是五十步和百步的區(qū)別)。
從分層角度來(lái)看,現(xiàn)在三層架構(gòu):表現(xiàn)層、業(yè)務(wù)層和持久層,三個(gè)層次應(yīng)該分割明顯,職責(zé)分明:持久層職責(zé)持久化保存業(yè)務(wù)模型對(duì)象,業(yè)務(wù)層對(duì)持久層的調(diào)用只是幫助我們激活曾經(jīng)委托其保管的對(duì)象,所以,不能因?yàn)槌志脤邮潜9苷撸覀兙鸵云錇楹诵膰@其編程,除了要求其歸還模型對(duì)象外,還要求其做其做復(fù)雜的業(yè)務(wù)組合。打個(gè)比喻:你在火車(chē)站將水果和盤(pán)子兩個(gè)對(duì)象委托保管處保管,過(guò)了兩天來(lái)取時(shí),你還要求保管處將水果去皮切成塊,放在盤(pán)子里,做成水果盤(pán)給你,合理嗎?
上面是談過(guò)分依賴持久層的一個(gè)現(xiàn)象,還有一個(gè)正好相反現(xiàn)象,持久層散發(fā)出來(lái),開(kāi)始擠占業(yè)務(wù)層,腐蝕業(yè)務(wù)層,整個(gè)業(yè)務(wù)層到處看見(jiàn)的是數(shù)據(jù)表的影子(包括數(shù)據(jù)表的字段),而不是業(yè)務(wù)對(duì)象。這樣程序員應(yīng)該多看看OO經(jīng)典PoEAA。PoEAA 認(rèn)為除了持久層,不應(yīng)該在其他地方看到數(shù)據(jù)表或表字段名。
當(dāng)然適量使用存儲(chǔ)過(guò)程,使用數(shù)據(jù)庫(kù)優(yōu)點(diǎn)也是允許的。按照Evans DDD理論,可以將SQL語(yǔ)句和存儲(chǔ)過(guò)程作為規(guī)則Specification一部分。
Hibernate等ORM問(wèn)題
現(xiàn)在使用Hibernate人也不少,但是他們發(fā)現(xiàn)Hibernate性能緩慢,所以尋求解決方案,其實(shí)并不是 Hibernate性能緩慢,而是我們使用方式發(fā)生錯(cuò)誤:
“最近本人正搞一個(gè)項(xiàng)目,項(xiàng)目中我們用到了struts1.2+hibernate3, 由于關(guān)系復(fù)雜表和表之間的關(guān)系很多,在很多地方把lazy都設(shè)置false,所以導(dǎo)致數(shù)據(jù)一加載很慢,而且查詢一條數(shù)據(jù)更是非常的慢。”
Hibernate是一個(gè)基于對(duì)象模型持久化的技術(shù),因此,關(guān)鍵是我們需要設(shè)計(jì)出高質(zhì)量的對(duì)象模型,遵循DDD領(lǐng)域建模原則,減少降低關(guān)聯(lián),通過(guò)分層等有效辦法處理關(guān)聯(lián)。如果采取圍繞數(shù)據(jù)表進(jìn)行設(shè)計(jì)編程,加上表之間關(guān)系復(fù)雜(沒(méi)有科學(xué)方法處理、偵察或減少這些關(guān)系),必然導(dǎo)致 系統(tǒng)運(yùn)行緩慢,其實(shí)同樣問(wèn)題也適用于當(dāng)初對(duì)EJB的實(shí)體Bean的CMP抱怨上,實(shí)體Bean是Domain Model持久化,如果不首先設(shè)計(jì)Domain Model,而是設(shè)計(jì)數(shù)據(jù)表,和持久化工具設(shè)計(jì)目標(biāo)背道而馳,能不出問(wèn)題嗎?關(guān)于這個(gè)問(wèn)題N多年就在Jdon爭(zhēng)論過(guò)。
關(guān)于本系列
PHP 是一種非常優(yōu)秀的 Web 開(kāi)發(fā)語(yǔ)言,而在商業(yè)應(yīng)用程序開(kāi)發(fā)方面,Java 編程語(yǔ)言十分流行。因此,為了在 AIX Version 5.3 操作系統(tǒng)上充分利用它們的優(yōu)勢(shì),專門(mén)開(kāi)發(fā)了 PHP Java Bridge。本系列文章向 AIX 5.3 開(kāi)發(fā)人員介紹了如何在他們的 Web 應(yīng)用程序開(kāi)發(fā)中集成 PHP 和 Java 技術(shù)。
為了說(shuō)明這一點(diǎn),您將按照典型的開(kāi)發(fā)過(guò)程來(lái)構(gòu)建一個(gè)簡(jiǎn)單的問(wèn)卷調(diào)查應(yīng)用程序,具體內(nèi)容包括:
開(kāi)發(fā)主要的 Java 應(yīng)用程序
通過(guò) Servlet 將 Java 應(yīng)用程序公開(kāi)為基于 Java 的 Web 應(yīng)用程序
添加在數(shù)據(jù)庫(kù)中存儲(chǔ)信息的支持
將原始應(yīng)用程序公開(kāi)為 Web Services,并為該應(yīng)用程序提供 PHP 接口
使用專門(mén)的 PHP Java Bridge 重新開(kāi)發(fā) PHP 接口
本系列文章共分為六個(gè)部分:
第 1 部分介紹了一個(gè)應(yīng)用程序,并為構(gòu)建 Java 應(yīng)用程序以及使用 Tomcat 執(zhí)行基于 Java 的 Web 應(yīng)用程序搭建了相應(yīng)的環(huán)境。
第 2 部分介紹了主要的應(yīng)用程序代碼以及一個(gè)簡(jiǎn)單的 Java Servlet 的開(kāi)發(fā),以便為信息提供一個(gè) Web 接口。
第 3 部分將核心應(yīng)用程序連接到 DB2? 數(shù)據(jù)庫(kù),以便對(duì)問(wèn)卷調(diào)查的問(wèn)題和回答進(jìn)行存儲(chǔ)。
第 4 部分對(duì)原始應(yīng)用程序進(jìn)行轉(zhuǎn)換,使其能夠作為 Web Services 進(jìn)行訪問(wèn),并且它為 PHP 接口提供了基礎(chǔ)。
第 5 部分使用 PHP Java Bridge 為 Java 應(yīng)用程序構(gòu)建 PHP 接口。
第 6 部分對(duì)這個(gè)應(yīng)用程序進(jìn)行重新開(kāi)發(fā),以便使用 PHP Java Bridge 來(lái)代替 Web Services 接口。
關(guān)于本教程
本教程是這個(gè)系列文章的最后一個(gè)部分,在本教程中,您將了解如何組合使用 PHP 和 Java 技術(shù),以便為支持問(wèn)卷調(diào)查應(yīng)用程序的原始 Java 類(lèi)構(gòu)建 Web 接口。這個(gè)最終解決方案使用 PHP Java Bridge 以使得您可以為在本系列文章的前面幾個(gè)部分中所開(kāi)發(fā)的 Java 類(lèi)構(gòu)建基于 PHP 的接口。
您首先將了解 PHP Java Bridge、以及它的操作與最初開(kāi)發(fā)的 Web 服務(wù)方法之間的區(qū)別,從而對(duì)這幾種不同的技術(shù)進(jìn)行比較。然后,在研究原始 Java 類(lèi)的 PHP 接口的最終備選方法之前,您將研究幾種不同的集成您的基于 PHP 和 Java 的解決方案。
先決條件
為了學(xué)習(xí)本教程,您需要安裝下列軟件:
IBM pSerIEs? 服務(wù)器(本文中的代碼使用 AIX Version 5.3 進(jìn)行了測(cè)試。)
Apache Tomcat 系統(tǒng)
Eclipse IDE
Java 5 64-bit SDK(要下載這個(gè)包,您需要進(jìn)行注冊(cè),但注冊(cè)是免費(fèi)的。)
Mozilla Web browser for AIX
幾種不同連接技術(shù)的比較
問(wèn)卷調(diào)查應(yīng)用程序所使用的 Web 服務(wù)方法為您提供了極大的靈活性,而 PHP Java Bridge 以不同的方式提供了類(lèi)似的靈活性。在您更深入地研究開(kāi)發(fā)過(guò)程之前,讓我們更仔細(xì)地分析一下它們之間的區(qū)別和相似之處。
Web 服務(wù)方法
您對(duì)原始應(yīng)用程序進(jìn)行了轉(zhuǎn)換,這樣一來(lái),在本系列文章的第四部分中(請(qǐng)參見(jiàn)參考資料),就可以將其作為 Web Services 進(jìn)行訪問(wèn)。除了可訪問(wèn)性之外,Web Services 模型還具有許多其它的優(yōu)點(diǎn)。通過(guò) Web Services 接口來(lái)公開(kāi)類(lèi),您可以保證互操作性,因?yàn)閹缀跛械恼Z(yǔ)言都支持某些形式的 Web Services ,無(wú)論是 XML-RPC 還是簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議 (SOAP)。
這也就帶來(lái)了極大的靈活性。現(xiàn)在,您的 Java 后端可以由采用 C、Perl、Java 語(yǔ)言、PHP、JavaScript 和許多其他編程語(yǔ)言所編寫(xiě)的腳本和應(yīng)用程序來(lái)進(jìn)行訪問(wèn);然而,實(shí)現(xiàn)互操作性是要付出一定代價(jià)的。
正如您在本系列文章的第四部分中所看到的,將您的應(yīng)用程序公開(kāi)為 Web Services 是一項(xiàng)復(fù)雜的任務(wù)。要正確地完成這項(xiàng)工作,需要通過(guò) Web 服務(wù)描述語(yǔ)言 (WSDL) 文件開(kāi)發(fā)和部署您的代碼;然后,您必須單獨(dú)地為每個(gè)函數(shù)定義不同的接口,同時(shí)還需要確保采用與您希望使用的標(biāo)準(zhǔn)可互操作的格式,對(duì)所提供的值和返回的值進(jìn)行編碼和封裝。
在您為核心類(lèi)開(kāi)發(fā)和添加新的功能和擴(kuò)展時(shí),所有的這些工作都需要花費(fèi)大量的時(shí)間進(jìn)行開(kāi)發(fā)、以及較長(zhǎng)的時(shí)間進(jìn)行控制。要使得原始類(lèi)能夠通過(guò) Web 服務(wù)接口進(jìn)行訪問(wèn),可能會(huì)使得您的開(kāi)發(fā)時(shí)間增加 20% 到 50%。
而且,正如稍后將更詳細(xì)地進(jìn)行介紹的,Web 服務(wù)方法還隱含了不容忽視的顯著性能開(kāi)銷(xiāo)(如果您希望在大型操作環(huán)境中部署該應(yīng)用程序的話)。
PHP Java Bridge
在本系列文章的第五部分中,您詳細(xì)地了解了 PHP Java Bridge(請(qǐng)參見(jiàn)參考資料),但是 PHP Java Bridge 的關(guān)鍵元素允許您直接從 PHP 內(nèi)部訪問(wèn) Java 類(lèi),就好像您正在訪問(wèn)本地 PHP 類(lèi)一樣。
盡管 Web 服務(wù)和 PHP Java Bridge 接口在本質(zhì)上存在很大的差別,但事實(shí)上,它們都使用 XML 進(jìn)行通信,以交換有關(guān)原始方法和類(lèi)、以及應(yīng)該如何對(duì)它們進(jìn)行訪問(wèn)的信息。與 Web 服務(wù)解決方案有所不同,這個(gè)過(guò)程是自動(dòng)的。
正如您在第五部分中所看到的(請(qǐng)參見(jiàn)參考資料)、以及本文清單 1 中所介紹的,在您導(dǎo)入 PHP 元素、并且創(chuàng)建到遠(yuǎn)程 Java 主機(jī)的連接之后,使用和創(chuàng)建 Java 類(lèi)和對(duì)象是非常簡(jiǎn)單的。
清單 1. 簡(jiǎn)單的 PHP Java Bridge 的示例 <? require_once("http://sulaco.mcslp.pri:8080/JavaBridge/java/Java.inc"); $System = new Java("java.lang.System"); print_r($System->getProperties); ?> |
在本教程后面的內(nèi)容中,您將研究所需的確切的方法和解決方案。
區(qū)別和相似之處
Web Services 和 PHP Java 解決方案之間存在許多明顯的區(qū)別和相似之處,從而使得采用這兩種方法開(kāi)發(fā)和部署應(yīng)用程序時(shí)具有相應(yīng)的優(yōu)點(diǎn)和缺點(diǎn)。
例如,Web 服務(wù)和 PHP Java Bridge 解決方案都允許您使用 PHP 作為前端、使用 Java 環(huán)境作為應(yīng)用程序的后端部分。對(duì)于 Web 服務(wù)解決方案,您必須開(kāi)發(fā)原始類(lèi)、Web 服務(wù)類(lèi)和 PHP 接口。對(duì)于 PHP Java Bridge,您只需要開(kāi)發(fā)原始 Java 類(lèi)和 PHP 前端,PHP Java Bridge 可以為您處理所有的互操作性問(wèn)題。
在 Web 服務(wù)和 PHP Java Bridge 解決方案之間還存在一個(gè)比較顯著的區(qū)別,即完成解決方案所需的步驟有所不同。Web 服務(wù)解決方案需要額外的開(kāi)發(fā)時(shí)間,以使用所需的 Web 服務(wù)接口來(lái)公開(kāi)服務(wù)、并使得它們可供使用。在 PHP 中使用 Web 服務(wù)也是相當(dāng)繁瑣的,因?yàn)槟仨氶_(kāi)發(fā)一個(gè)能夠?yàn)橐验_(kāi)發(fā)的 Web 服務(wù)接口提供接口的解決方案。
對(duì)于 PHP Java Bridge,您可以直接訪問(wèn)現(xiàn)有的 Java 類(lèi),而不必在 Java 端顯式地開(kāi)發(fā)接口、或者在 PHP 端顯式地開(kāi)發(fā)訪問(wèn)接口。
性能
為了將您的原始請(qǐng)求轉(zhuǎn)換為完全與平臺(tái)無(wú)關(guān)的形式,使用 Web 服務(wù)的關(guān)鍵問(wèn)題之一是必須將請(qǐng)求轉(zhuǎn)換為 XML。所得到的 XML 數(shù)據(jù)包中包括請(qǐng)求、源或目標(biāo)信息、以及請(qǐng)求中所包含的任何數(shù)據(jù)或者信息(例如,方法或函數(shù)的參數(shù)),這使得 XML 組件的負(fù)載變得非常大。
采用這種方式生成有效的 XML 是相當(dāng)花費(fèi)時(shí)間的,但是對(duì)該信息進(jìn)行解碼甚至可能需要花費(fèi)更多的時(shí)間,因?yàn)?XML 解析的過(guò)程并不像您所預(yù)期的那么簡(jiǎn)單和直接。和發(fā)送請(qǐng)求到服務(wù)器的客戶端的負(fù)載相比,這個(gè)處理過(guò)程會(huì)呈現(xiàn)更高的負(fù)載,隨后還會(huì)有接受請(qǐng)求和最后處理請(qǐng)求的過(guò)程。在將響應(yīng)發(fā)送回客戶端的時(shí)候,將按相反的順序執(zhí)行相同的處理過(guò)程(采用 XML 對(duì)響應(yīng)進(jìn)行編碼,發(fā)送到客戶端,客戶端解析 XML 并且提取響應(yīng))。
您可以在圖 1 中更詳細(xì)地看到這個(gè)過(guò)程。
圖 1. 實(shí)際應(yīng)用中的 Web 服務(wù)接口 ]]>一、ODBC到JDBC的發(fā)展歷程
說(shuō)到JDBC,很容易讓人聯(lián)想到另一個(gè)十分熟悉的字眼ODBC。它們之間有沒(méi)有聯(lián)系呢?如果有,那么它們之間又是怎樣的關(guān)系呢?
ODBC是OpenDatabaseConnectivity的英文簡(jiǎn)寫(xiě)。它是一種用來(lái)在相關(guān)或不相關(guān)的管理系統(tǒng)(DBMS)中存取數(shù)據(jù)的,用C語(yǔ)言實(shí)現(xiàn)的,標(biāo)準(zhǔn)應(yīng)用程序數(shù)據(jù)接口。通過(guò)ODBCAPI,應(yīng)用程序可以存取保存在多種不同管理系統(tǒng)(DBMS)中的數(shù)據(jù),而不論每個(gè)DBMS使用了何種數(shù)據(jù)存儲(chǔ)格式和編程接口。
1.ODBC的結(jié)構(gòu)模型
ODBC的結(jié)構(gòu)包括四個(gè)主要部分:應(yīng)用程序接口、驅(qū)動(dòng)器管理器、驅(qū)動(dòng)器和數(shù)據(jù)源。
應(yīng)用程序接口:屏蔽不同的ODBC驅(qū)動(dòng)器之間函數(shù)調(diào)用的差別,為用戶提供統(tǒng)一的SQL編程接口。
驅(qū)動(dòng)器管理器:為應(yīng)用程序裝載驅(qū)動(dòng)器。
驅(qū)動(dòng)器:實(shí)現(xiàn)ODBC的函數(shù)調(diào)用,提供對(duì)特定數(shù)據(jù)源的SQL請(qǐng)求。如果需要,驅(qū)動(dòng)器將修改應(yīng)用程序的請(qǐng)求,使得請(qǐng)求符合相關(guān)的DBMS所支持的文法。
數(shù)據(jù)源:由用戶想要存取的數(shù)據(jù)以及與它相關(guān)的操作系統(tǒng)、DBMS和用于DBMS的網(wǎng)絡(luò)平臺(tái)組成。
雖然ODBC驅(qū)動(dòng)器管理器的主要目的是加載驅(qū)動(dòng)器,以便ODBC函數(shù)調(diào)用,但是驅(qū)動(dòng)器本身也執(zhí)行ODBC函數(shù)調(diào)用,并與相互配合。因此當(dāng)應(yīng)用系統(tǒng)發(fā)出調(diào)用與數(shù)據(jù)源進(jìn)行連接時(shí),驅(qū)動(dòng)器能管理通信協(xié)議。當(dāng)建立起與數(shù)據(jù)源的連接時(shí),驅(qū)動(dòng)器便能處理應(yīng)用系統(tǒng)向DBMS發(fā)出的請(qǐng)求,對(duì)分析或發(fā)自數(shù)據(jù)源的設(shè)計(jì)進(jìn)行必要的翻譯,并將結(jié)果返回給應(yīng)用系統(tǒng)。
2.JDBC的誕生
自從Java語(yǔ)言于1995年5月正式公布以來(lái),Java風(fēng)靡全球。出現(xiàn)大量的用java語(yǔ)言編寫(xiě)的程序,其中也包括應(yīng)用程序。由于沒(méi)有一個(gè)Java語(yǔ)言的API,編程人員不得不在Java程序中加入C語(yǔ)言的ODBC函數(shù)調(diào)用。這就使很多Java的優(yōu)秀特性無(wú)法充分發(fā)揮,比如平臺(tái)無(wú)關(guān)性、面向?qū)ο筇匦缘取kS著越來(lái)越多的編程人員對(duì)Java語(yǔ)言的日益喜愛(ài),越來(lái)越多的公司在Java程序開(kāi)發(fā)上投入的精力日益增加,對(duì)java語(yǔ)言接口的的API的要求越來(lái)越強(qiáng)烈。也由于ODBC的有其不足之處,比如它并不容易使用,沒(méi)有面向?qū)ο蟮奶匦缘鹊龋琒UN公司決定開(kāi)發(fā)一Java語(yǔ)言為接口的應(yīng)用程序開(kāi)發(fā)接口。在JDK1.x版本中,JDBC只是一個(gè)可選部件,到了JDK1.1公布時(shí),SQL類(lèi)包(也就是JDBCAPI)就成為Java語(yǔ)言的標(biāo)準(zhǔn)部件。
二、JDBC技術(shù)概述
JDBC是一種可用于執(zhí)行SQL語(yǔ)句的JavaAPI(ApplicationProgrammingInterface,應(yīng)用程序設(shè)計(jì)接口)。它由一些Java語(yǔ)言寫(xiě)的類(lèi)、界面組成。JDBC給應(yīng)用開(kāi)發(fā)人員、前臺(tái)工具開(kāi)發(fā)人員提供了一種標(biāo)準(zhǔn)的應(yīng)用程序設(shè)計(jì)接口,使開(kāi)發(fā)人員可以用純Java語(yǔ)言編寫(xiě)完整的應(yīng)用程序。
通過(guò)使用JDBC,開(kāi)發(fā)人員可以很方便地將SQL語(yǔ)句傳送給幾乎任何一種。也就是說(shuō),開(kāi)發(fā)人員可以不必寫(xiě)一個(gè)程序Sybase,寫(xiě)另一個(gè)程序Oracle,再寫(xiě)一個(gè)程序Microsoft的SQLServer。用JDBC寫(xiě)的程序能夠自動(dòng)地將SQL語(yǔ)句傳送給相應(yīng)的管理系統(tǒng)(DBMS)。不但如此,使用Java編寫(xiě)的應(yīng)用程序可以在任何支持Java的平臺(tái)上運(yùn)行,不必在不同的平臺(tái)上編寫(xiě)不同的應(yīng)用。Java和JDBC的結(jié)合可以讓開(kāi)發(fā)人員在開(kāi)發(fā)應(yīng)用時(shí)真正實(shí)現(xiàn)WriteOnce,RunEverywhere!
Java具有健壯、安全、易用等特性,而且支持自動(dòng)網(wǎng)上下載,本質(zhì)上是一種很好的應(yīng)用的編程語(yǔ)言。它所需要的是Java應(yīng)用如何同各種各樣的連接,JDBC正是實(shí)現(xiàn)這種連接的關(guān)鍵。
JDBC擴(kuò)展了Java的能力,如使用Java和JDBCAPI就可以公布一個(gè)Web頁(yè),頁(yè)中帶有能遠(yuǎn)端的Ap?plet。或者企業(yè)可以通過(guò)JDBC讓全部的職工(他們可以使用不同的操作系統(tǒng),如Windwos,Machintosh和UNIX)在In?tranet上連接到幾個(gè)全球上,而這幾個(gè)全球可以是不相同的。隨著越來(lái)越多的程序開(kāi)發(fā)人員使用Java語(yǔ)言,對(duì)Java易操作性的需求越來(lái)越強(qiáng)烈。
MIS管理人員喜歡Java和JDBC,因?yàn)檫@樣可以更容易經(jīng)濟(jì)地公布信息。各種已經(jīng)安裝在中的事務(wù)處理都將繼續(xù)正常運(yùn)行,甚至這些事務(wù)處理是存儲(chǔ)在不同的管理系統(tǒng)中;而對(duì)新的應(yīng)用來(lái)說(shuō),開(kāi)發(fā)時(shí)間將縮短,安裝和版本升級(jí)將大大簡(jiǎn)化。程序員可以編寫(xiě)或改寫(xiě)一個(gè)程序,然后將它放在服務(wù)器上,而每個(gè)用戶都可以服務(wù)器得到最新的版本。對(duì)于信息服務(wù)行業(yè),Java和JDBC提供了一種很好的向外界用戶更新信息的方法。
1.JDBC的任務(wù)
簡(jiǎn)單地說(shuō),JDBC能完成下列三件事:
1)同一個(gè)建立連接;
2)向發(fā)送SQL語(yǔ)句;
3)處理返回的結(jié)果。
]]>新技術(shù)采用概況
許多分析家擁有技術(shù)應(yīng)用所需的描述模型。其中最為流行的模型是定義在Ruby的Web開(kāi)發(fā)框架Iowa中,用來(lái)描述農(nóng)產(chǎn)品的應(yīng)用,稍后在一本由Geoffrey A. Moore寫(xiě)作的名為《跨越鴻溝》(Crossing the Chasm)的書(shū)中,被用來(lái)描述技術(shù)內(nèi)容。在書(shū)中,Moore分析了技術(shù)應(yīng)用周期中存在著的五個(gè)截然不同的群體:
技術(shù)專家。這個(gè)群體傾向于采用新的技術(shù)。任何一種有前途的技術(shù)都會(huì)引起這個(gè)群體的注意。
先行采納者。不管這項(xiàng)技術(shù)是否在主流技術(shù)中取得成功,這個(gè)群體都將會(huì)采用新的技術(shù)來(lái)提升競(jìng)爭(zhēng)優(yōu)勢(shì)。
實(shí)用主義者。一旦新的技術(shù)進(jìn)入主流應(yīng)用,或是有足夠陡峭的增長(zhǎng)曲線來(lái)保證技術(shù)將得到廣泛采用,那么實(shí)用主義者就會(huì)積極采用新的技術(shù)。
保守派。只有新技術(shù)成為必須的時(shí)候,他們才會(huì)考慮采用新的技術(shù)。
懷疑論者。這個(gè)群體可能很晚才會(huì)采用新的技術(shù),或者也可能永遠(yuǎn)只使用某一特定技術(shù)。
Moore指出,技術(shù)應(yīng)用的關(guān)鍵之處在于團(tuán)隊(duì)中是否存在實(shí)用主義者。因?yàn)閷?shí)用主義者需要新技術(shù)大規(guī)模的應(yīng)用,這個(gè)中間群體希望看到其他務(wù)實(shí)派在團(tuán)隊(duì)做出承諾之前就使用新的技術(shù)。這是一個(gè)類(lèi)似于《第二十二條軍規(guī)》書(shū)中所描述的現(xiàn)象,因?yàn)閯?wù)實(shí)派們都會(huì)相互依賴的存在。出于這樣的原因,在先行采納者排列在技術(shù)專家之后和務(wù)實(shí)派之前,你會(huì)經(jīng)常在市場(chǎng)接受度曲線中看到一種下降的趨勢(shì)。Moore將這種下降稱之為鴻溝傾向,并且這種想法應(yīng)出于圍繞任何新技術(shù)的風(fēng)險(xiǎn)討論的中心。
]]>
基于JVM的語(yǔ)言正在開(kāi)始流行
當(dāng)Sun Microsystems公司在1995年第一次揭開(kāi)Java的面紗的時(shí)候,就是非常難被定義的。這是因?yàn)镴AVA是由多個(gè)部分構(gòu)成:首先,它當(dāng)然是一個(gè)面向?qū)ο笳Z(yǔ)言。同時(shí)JAVA也是一個(gè)定義標(biāo)準(zhǔn)的語(yǔ)言(或多個(gè)標(biāo)準(zhǔn),包括移動(dòng)設(shè)備,標(biāo)準(zhǔn),和企業(yè)三個(gè)版本)。最后,Java是一個(gè)虛擬機(jī)(”JVM”),一個(gè)Java程序能夠執(zhí)行的軟件環(huán)境。如果你有一個(gè)JVM,雖然這個(gè)JVM只能用來(lái)運(yùn)行Java的程序——但是,JVM能在運(yùn)行在你能想到的每一個(gè)平臺(tái)之上,這使得Java成為一個(gè)具有高移植性的語(yǔ)言。
在Java世界的一個(gè)令人著迷的趨勢(shì)就是:在最近的幾年里使用JVM來(lái)運(yùn)行非Java的程序在程增長(zhǎng)的趨勢(shì)。畢竟,如果創(chuàng)造了一門(mén)新的語(yǔ)言,你就必須在特定的平臺(tái)上實(shí)現(xiàn)它。如果你想你的語(yǔ)言能在不同的平臺(tái)上移植,那么你就需要為每一個(gè)平臺(tái)實(shí)現(xiàn)一個(gè)版本。但是,相比而言,如果你將語(yǔ)言實(shí)現(xiàn)在JVM上,那么你就能讓你的語(yǔ)言運(yùn)行在任何系統(tǒng)的JVM上,這就意味著幾乎所有平臺(tái)都可以運(yùn)行。
于是現(xiàn)在就有了許多的基于JVM的新增語(yǔ)言。其中4個(gè)最流行的是發(fā)布在開(kāi)源許可證之下的。考慮到如今Java也是開(kāi)發(fā)源碼了,這意味著你可以使用一個(gè)全開(kāi)源體系,并且這個(gè)體系是可以移植的。因?yàn)檫@些語(yǔ)言都在JVM之上實(shí)現(xiàn)的,所以你就可以同時(shí)訪問(wèn)Java的標(biāo)準(zhǔn)庫(kù)。這意味著如果有一個(gè)第三方的的 Java庫(kù),而且你精于Python,那么你就可以使用Jython在你的源代碼中訪問(wèn)這些Java庫(kù)。
早期的基于JVM的腳本語(yǔ)言,就我所知,是Jython,之前被稱為JPython。Jython,從名字你就可以猜到,是一個(gè)基于JVM的 Python語(yǔ)言實(shí)現(xiàn)。Jython完全兼容Python2.2的標(biāo)準(zhǔn)版本(這個(gè)標(biāo)準(zhǔn)版本的Python也被稱為CPython),這意味著Jython 將會(huì)沒(méi)有Python的一些新特性。最近發(fā)布的Jython版本是2007年月發(fā)布的,但是Sun雇傭了兩位早期Jython非常知名的開(kāi)發(fā)者,并且現(xiàn)在 Jython可以運(yùn)行Django應(yīng)用程序框架,因此驗(yàn)證其兼容Python的能力
Sun公司同時(shí)資助了JRuby的開(kāi)發(fā),一個(gè)基于JVM的Ruby版本。Jython是Python唯一的兩個(gè)實(shí)現(xiàn)的其中之一,對(duì)比而言,JRuby則是眾多Ruby語(yǔ)言實(shí)現(xiàn)的其中之一。然而,JRuby被廣泛的認(rèn)為是一個(gè)非常重要的版本。特別是因?yàn)樗男剩透叨燃嫒輼?biāo)準(zhǔn)C的 Ruby版本實(shí)現(xiàn)。JRuby同樣可以運(yùn)行Ruby on Rails框架(譯者注:構(gòu)建在Ruby之上的WEB應(yīng)用框架),此外還能運(yùn)行其他眾多的功能。
Jython和JRuby都是從其他已存在的語(yǔ)言中移植到JVM中來(lái)的。而全新的基于JVM的腳本語(yǔ)言是Groovy和Scala。這兩門(mén)語(yǔ)言現(xiàn)在都越來(lái)越流行,不同的是,Groovy是動(dòng)態(tài)腳本語(yǔ)言,而是Scala是靜態(tài)語(yǔ)言。使用Groovy最著名的應(yīng)用是Groovy on Grails項(xiàng)目,一個(gè)用Groovy寫(xiě)成,運(yùn)行在JVM之上的WEB應(yīng)用框架(和Ruby on Rails很相似)。Grails找到通向商業(yè)應(yīng)用程序的道路,最著名的就是LinkedIn,使用Linkedin,開(kāi)發(fā)人員發(fā)現(xiàn)他們能比直接使用 Java更快速和容易的開(kāi)發(fā)程序。相比而言,Scala,而是強(qiáng)類(lèi)型是語(yǔ)言,Steve Yegge最近的一次訪談中曾經(jīng)談到、靜態(tài)語(yǔ)言和動(dòng)態(tài)語(yǔ)言的爭(zhēng)論,因?yàn)檫@個(gè)他還受到了很多的批評(píng)(譯者注:關(guān)于Steve Yegge的這篇關(guān)于動(dòng)態(tài)語(yǔ)言和靜態(tài)語(yǔ)言之爭(zhēng)可以查看這里Steve Yegge是一個(gè)動(dòng)態(tài)語(yǔ)言的支持者)
Java已經(jīng)被公認(rèn)為是非常成功而流行的語(yǔ)言。現(xiàn)在,Java也同時(shí)也被認(rèn)為是非常流行的平臺(tái),這四類(lèi)語(yǔ)言僅僅是在不遠(yuǎn)的將來(lái)通過(guò)JVM來(lái)實(shí)現(xiàn)的新興語(yǔ)言的開(kāi)始。
]]>