http://java.ccidnet.com/art/297/20060508/547541_1.html
本文試圖比較同屬快速開發(fā)性質(zhì)的Ruby on Rails(以下簡稱RoR)和Jdon Framework(以下簡稱JF)在架構(gòu)上異同,供大家在實際架構(gòu)選擇中比較。
RoR 是一個使用Ruby語言寫就的Web應(yīng)用框架,Ruby語言是類似Python, Smalltalk, PHP和Perl的動態(tài)類型語言。從新特點層面看,Ruby on Rails并沒有提供比其他已經(jīng)存在的Web應(yīng)用框架新的東西,它的唯一特點就是快速開發(fā)。RoR大概誕生于2004年6月份。
JF是使用Java語言編寫的、基于Ioc/AOP微容器的快速開發(fā)工具。JF是基于JdonSD構(gòu)件庫增刪改查框架基礎(chǔ)上發(fā)展起來的,1.0版本是在2004 年12月底完成。當(dāng)時推出時很難定位,時至今日,它應(yīng)該是Ruby on Rails、Spring和JBoss容器三個概念的一個中間體。屬于域驅(qū)動開發(fā)框架(DDDD:omain Driven Development framework )。
JF雖是筆者操作完成,其實它是國人網(wǎng)絡(luò)結(jié)晶的開源產(chǎn)物,很多需求和思想都來自Jdon社區(qū)熱情參與者,看到很多初學(xué)者總是為簡單和靈活做痛苦選擇,為了寫一個簡單系統(tǒng),要么走入Jsp+JavaBeans誤區(qū),要么被復(fù)雜技術(shù)配置纏身,忘記業(yè)務(wù)本職工作。JF 推出后,道友提出各種建議甚至猛烈批判,這些都形成了JF發(fā)展動力,促進(jìn)JF完善。從用戶出發(fā)的簡易之道使JF的起點和立意一下和RoR這樣國外產(chǎn)品走到了一起,下面我們詳細(xì)進(jìn)行一下兩者架構(gòu)比較。
語言之爭
RoR代表的是動態(tài)類型語言派別;而Java是一種靜態(tài)類型語言,當(dāng)初Java剛剛誕生時,這種兩種類型派別之爭曾經(jīng)發(fā)生在Java和Smalltalk之間,后來現(xiàn)實選擇了Java這樣靜態(tài)類型語言,關(guān)鍵原因時動態(tài)類型語言在編程時難以找出其一些潛在的語言Bug。
但是,隨著軟件工程中單元測試的重視,動態(tài)類型語言+單元測試的結(jié)合克服了以上缺憾,從而使得RoR這樣得動態(tài)類型語言重新東山再起。
促成RoR受到敏捷工程派別的領(lǐng)域?qū)<遥ㄈ鏜artin Fowler)推崇另外一個原因是,它被認(rèn)為是一種domain-specific languages(DSL)實現(xiàn),DSL是一種專門供領(lǐng)域建模專家(也就是系統(tǒng)分析師)使用的語言,這些領(lǐng)域?qū)<也煌诔绦蚋呤郑麄冇幸惶鬃约赫J(rèn)知世界和表達(dá)世界的思維和方式(如UML),因此,他們不感興趣于軟件設(shè)計細(xì)節(jié),希望軟件能夠按照他們分析設(shè)計的結(jié)果去運行和執(zhí)行就可以了。
其實,DSL并不是一個全新理念,它已經(jīng)在我們軟件領(lǐng)域中反復(fù)出現(xiàn),例如:我們很多人是關(guān)系數(shù)據(jù)庫領(lǐng)域?qū)<遥裕M管由O/R Mapping這樣工具出現(xiàn),但是并沒有改變這些領(lǐng)域?qū)<冶磉_(dá)方式,他們還是使用SQL等嚴(yán)謹(jǐn)?shù)臄?shù)學(xué)思維來實現(xiàn)他們的表達(dá)方式。
DSL概念非常好,但是是否有必要重新搞一套DSL語言則涉及很多方面的問題,新的語言總會在實踐中有新的陷阱,Java經(jīng)過十多年發(fā)展,成熟和發(fā)展是其特點。
當(dāng)然,別以為RoR頂著DSL新名詞就是一個非常好的東西,對其本質(zhì)微詞已經(jīng)不絕于耳,有人認(rèn)為它實質(zhì)不過就是1994的Visual FoxPro(Ruby on Rails is a Bloody Square Turd ),提出該觀點的作者認(rèn)為:為什么我們在一個沒有重構(gòu)以及調(diào)試支持的編碼環(huán)境中工作?為什么還要重覆以前的痛苦呢?如果你確實喜歡RoR的ActiveRecord,為什么不用. NET呢?RoR 不是開發(fā)Web應(yīng)用平臺, RoR is a cult(RoR是宗教崇拜,筆者注:大概因為是因為所謂大師級的人推薦原因).
無論如何,讓我們拋開爭執(zhí),通過比較看看RoR一些特點。
多層架構(gòu)
現(xiàn)在多層架構(gòu)已經(jīng)深入人心,多層主要是指表現(xiàn)層MVC、業(yè)務(wù)層和持久層多層分離的體系,由于Java是一個技術(shù)自由選擇的世界,因此,每個層面都有不同的具體框架技術(shù)供選擇, 提供選擇是一種好事,但是又可能是一種壞事,需要應(yīng)用者花費精力學(xué)習(xí)和研究,這非常類似我們購物。
在微軟世界,由于各層框架技術(shù)幾乎都是由一家提供的,所以,.NET就索性將這些框架直接集成到IDE開發(fā)工具,對于有的程序員感覺.NET用起來很快,將開發(fā)工具和框架混合成一體,但這是以綁定為代價的,甚至有程序員反感Java世界IDE+框架的開發(fā)方式,認(rèn)為在開發(fā)工具之外還會多一個框架,并且認(rèn)為違背KISS(keep it simple and stupid)原則,其實不然,關(guān)鍵是追求KISS原則的同時,不要使自己受制于某個廠商或平臺,使自己變得簡單以及愚蠢
(失去自己作為客戶的上帝位置,被廠商忽視,成為簡單而愚蠢的人),此為KMSS(keep me simple and stupid)。
在Java世界,多層結(jié)構(gòu)實現(xiàn)路徑很多,從MVC到持久層框架有各種選擇,例如我們可以使用Struts以及Hibernate組合成一個J2EE多層 應(yīng)用系統(tǒng)。
Rails也提供了model/view/controller多層實現(xiàn),但是各層的實現(xiàn)框架也確定下來,省卻了程序員在多個框架之間選擇帶來的“麻煩”(這是相對的)。
而Jdon Framework則類似RoR這種提供缺省各層實現(xiàn)設(shè)計,表現(xiàn)層在struts基礎(chǔ)上進(jìn)行了CRUD流程抽象;通過提供JdbcTemp實現(xiàn)持久層技術(shù),當(dāng)然,持久層具體實現(xiàn)也可以選擇hibernate等其他框架實現(xiàn),秉承提供缺省的,但是也是可替換的宗旨。
下圖是兩者各層架構(gòu)比較圖:
我們通過上圖可以看出,兩者流程基本一致,所不同的主要是兩點:RoR的Action Pack和Active Record,下面我們就這兩點解釋如下:
Action Pack
Action Pack是RoR的MVC組件框架:
View templates,相當(dāng)于Struts中的Jsp;
URL routing,相當(dāng)于struts-config.xml流程配置,RoR不是使用XML配置,而是作為腳本代碼,這也是一些人吹噓的RoR無繁多 XML配置真相所在,其實,XML也是一種腳本,從某種意義上來說:XML比語言腳本更簡單易寫(至少語法不多)。
ActionController,初看相當(dāng)于struts的DispatchAction,但是因為其包含業(yè)務(wù)邏輯,而我們在java中是不推薦在在控制層action中寫業(yè)務(wù)邏輯的。
ActionController功能在于:RoR可以將瀏覽器的請求直接映射到ActionController類的方法上,這有些類似Struts 中的DispatchAction,但是,在Java中,業(yè)務(wù)邏輯是不推薦寫在表現(xiàn)層的控制類中的,控制類只是負(fù)責(zé)前后臺流程協(xié)調(diào),是一種 Mediator模式實現(xiàn),不應(yīng)該讓其加入更多職責(zé);在JF中,業(yè)務(wù)邏輯是寫在Service類中,JF通過自己的命令服務(wù)調(diào)用模式,也可以直接將瀏覽器的請求直接映射到Service類的方法上,例如,調(diào)用http://localhost//MyWeb/abc.do?method=xxx,將直接激活Service類的xxx方法,程序員直接編寫xxx方法內(nèi)容即可。
RoR的Filters過濾器也是Action Pack的一個部分,主要用來實現(xiàn)一些通用功能的動態(tài)插入,這在JF中是通過AOP攔截器和Decorator模式來實現(xiàn)的,見AOP vs Decorator 一文,在JiveJdon3.0中,我們通過攔截器實現(xiàn)了組件方法權(quán)限訪問、以及緩存等通用功能。
Action Pack中還有Helpers功能相當(dāng)于Struts的標(biāo)簽庫,它可以把Model/ActionForm和Action以及html連接在一起,下面是RoR的Helpers如:
Name: <%= text_field "person", "name", "size" => 20 %>
....
當(dāng)然,RoR的Helpers有很多種類,如Form Helpers/javascriptHelpers等等,相當(dāng)于一個個API 庫。它的Ajax & JavaScript helpers倒是很時髦的。
RoR的Layouts相當(dāng)于Struts的Tiles,這就不多說了。
Scaffolding提供一個數(shù)據(jù)表的CRUD功能實現(xiàn),Scaffolding類似代碼生成器,生成CRUD代碼,缺點是,如果你更改了代碼, Scaffolding會在覆蓋,必須再更改Scaffolding設(shè)置,實際用起來比較麻煩。而JF的CRUD是一個MVC流程上的精簡,屬于開發(fā)框架性質(zhì),而不是代碼生成,只需要通過jdonframework.xml配置:
Active Record
RoR有一個Active Record組件,其實就是ORM實現(xiàn),相當(dāng)于Hibernate,它是Martin Fowler的 Active Record pattern實現(xiàn),它是指一個既包含數(shù)據(jù)又包含行為的對象,這些數(shù)據(jù)需要持久保存到對應(yīng)的數(shù)據(jù)表中。Active Record一個很明顯的特征是:將數(shù)據(jù)訪問邏輯也包含在這個domain對象中,通過這種辦法讓人們可以知道如何從數(shù)據(jù)庫讀寫數(shù)據(jù)。如下圖:
Active Record其實類似JF中Domain Object + Dao,也就是將Dao中對數(shù)據(jù)庫的CRUD方法和Domain Object整合在一起,我們知道,Dao模式本質(zhì)是橋模式,通過Dao可以將不同的數(shù)據(jù)庫訪問實現(xiàn)分離,并且在運行時組合,但是,Martin Fowler將Dao從Domain Object分離出去的對象稱為貧血對象。
他的這個觀點筆者認(rèn)為不是從技術(shù)觀點,而是從領(lǐng)域建模角度出發(fā)的,其實從技術(shù)觀點講,將Dao從Domain Object中分離在設(shè)計上非常靈活,例如使用JF開發(fā)的JiveJdon3.0中,我們就可以在Dao層中使用Decorator模式(過濾器)加入一層緩存,這樣,雖然我們Dao層使用的SQL實現(xiàn),我們也是可以實現(xiàn)持久層緩存,JiveJdon3.0整個Dao層設(shè)計相當(dāng)于一個Hibernate的微型(或者說輕量化),好處是:JiveJdon3.0這樣實現(xiàn)的緩存可以被各層如表現(xiàn)層直接訪問,減少路徑,提升運行性能。
RoR秘籍
通過以上分析,我們也許已經(jīng)明白RoR和JF定位,大家為什么突然擁戴RoR,這是因為大家比較厭惡XML配置,太復(fù)雜的XML配置只能增加開發(fā)的復(fù)雜性,而JF則在這方面從以下幾個方面進(jìn)行了努力:
1. 表現(xiàn)層的struts-config.xml配置是模板化的,CRUD流程固化模板化,拷貝粘貼就可以完成配置。
2. JF自身的配置很簡單,只包括兩個部分Models和Services,配置語法主要集中再Models部分,語法數(shù)量不超過10個,Models負(fù)責(zé)CRUD流程配置,如果你不需要使用CRUD可以不用配置;Services是業(yè)務(wù)類配置,對于一個POJO類,只要寫:如下:
class="com.jdon.jivejdon.service.imp.ForumServiceImp"/>
class="com.jdon.jivejdon.service.imp.ForumMessageShell"/>
至于,這些POJO之間的調(diào)用關(guān)系,無需指定,這由JF內(nèi)置IOC微容器自動配對解決。
3. 持久層試圖通過JdbcTemp或SQL語句簡化配置,當(dāng)然Hibernate等java工具也在進(jìn)步,不斷重構(gòu),相信會越來越簡單。
總結(jié):相比RoR,作為DDD(Domain Driven Development framework )實現(xiàn)的JF在快速開發(fā)和軟件高質(zhì)量上作了一個平衡,相當(dāng)于在RoR(快速,但非主流語言)和Spring(高質(zhì)量,但配置煩瑣)之間做了一個平衡。
JF一直也試圖爭取獲得國外軟件專家的認(rèn)可,可能會因為其他因素未能如愿,但是,作為和RoR幾乎同時誕生的國產(chǎn)JF,作為由國人網(wǎng)民共同參與的結(jié)晶,已經(jīng)用事實證明,國人有能力靠創(chuàng)新沖刺世界軟件領(lǐng)域的前列。
無論如何,在RoR精神的召引下,Java世界將引來第四代語言4GL時代,同時能夠滿足求簡單或求靈活等不同編程心理的需求,迎來新的發(fā)展