Web開發(fā)誰更高效 Java對決Ruby on Rails
原創(chuàng)【51CTO快譯】Ruby on rails是如此的優(yōu)雅,簡單,以及高效。我總是讀到及聽到諸如此類的評價。比如Bill Walton在他的《Rolling with Ruby on Rails Revisited》一文中就這樣寫到:
“現(xiàn)在我告訴你,通過Rails開發(fā)一個web應(yīng)用能夠比傳統(tǒng)的Java框架快至少十倍,你會怎么想?”
哦,聽聽!快十倍!
事實上,聽到了這些評論之后,我決定學(xué)習(xí)Ruby on Rails。我需要了解生產(chǎn)力以及編程樂趣的真正關(guān)鍵所在。
而摸了摸RoR之后,我發(fā)現(xiàn)它是一個非常傳統(tǒng)的框架,使用著過時的技術(shù):
◆Ruby是動態(tài)語言,這與Smalltalk一樣。我偏愛靜態(tài)語言。
◆Scaffolding使用被動的代碼生成,這與IDE wizards或AppFuse一樣。 我偏愛主動的代碼生成,甚至更好的是沒有代碼生成。
◆以關(guān)系數(shù)據(jù)庫為中心:代碼生成器與ActiveRecord引導(dǎo)開發(fā)者先構(gòu)思表格,其次才是類。我偏愛更加純粹的OO,比如Hibernate,JPA,甚或是ODBMS。
◆MVC:我本來希望看到一個比老式MVC框架更有新意、更好的MVC。
Java的問題:Java開發(fā)者
Java世界中的生產(chǎn)力是個文化問題,而并非技術(shù)問題。那并非是Java的錯,而是因為我們。我們Java開發(fā)者需要設(shè)計非常美觀的架構(gòu),將GoF模式隨處應(yīng)用,實現(xiàn)一切(代碼的)重復(fù)利用,將3 tiers放進我們所有的系統(tǒng)中,并為所有(產(chǎn)品)使用web服務(wù)。我們追求的不是簡潔,所以我們才沒有找到它。然而Java是個優(yōu)雅的語言,使用它可以進行更加簡單的軟件開發(fā)。
Java的生產(chǎn)力:另一個渠道
提高生產(chǎn)力的方法之一是使用模型驅(qū)動的法子。那就是,開發(fā)模型的部分,事實上也僅僅開發(fā)我們應(yīng)用中那模型的部分;然后用一個框架來以此為基礎(chǔ)實現(xiàn)所有應(yīng)用的開發(fā)。MDA,OpenXava,Trails,NakedObjects,RomaFramework以及JMatter都屬于此類。
目的
我們要做的應(yīng)用主界面外觀如下:
基本上,該應(yīng)用旨在實現(xiàn)以下三個功能:
◆顯示食譜列表
◆創(chuàng)建新食譜,以及編輯現(xiàn)有食譜
◆將食譜歸類(如“甜點”或“湯類”)
#p#
Ruby on Rails的***沖鋒
RoR中,***步是創(chuàng)建一個新項目。在命令行下輸入如下字段:
$ rails cookbook2 |
然后,創(chuàng)建并設(shè)置數(shù)據(jù)庫。
之后則開始編寫最初的代碼。這里的話是SQL代碼:
drop table if exists recipes; |
很明顯,你需要在數(shù)據(jù)庫中執(zhí)行以上代碼。
***就是,生成Ruby代碼。你需要做的只是在你OS的shell下執(zhí)行如下指令:
$ ruby script\generate scaffold recipe recipe $ ruby script\generate scaffold category category |
是的。你的RoR應(yīng)用的最初版已經(jīng)可以運行了。
是的,花費很少的功夫,一個簡單的“create table”,外加執(zhí)行一個wizard。接下來就是看看結(jié)果了。
Rails的結(jié)果
開發(fā)成果如下:
少干活,少結(jié)果。
#p#
JPA on OX的***沖鋒
現(xiàn)在輪到OpenXava了。OpenXava下的***步是創(chuàng)建一個新項目:
$ ant CreateNewProject.xml -Dproject=CookBook |
然后,創(chuàng)建并設(shè)置數(shù)據(jù)庫。
之后則是最初的代碼編寫,這里自然是Java:
Recipe.java:
package org.openxava.cookbook.model; |
Category.java:
package org.openxava.cookbook.model; |
***一步則是生成數(shù)據(jù)庫圖表,只要執(zhí)行如下ant target即可:
$ ant updateSchema |
是的。你的OpenXava應(yīng)用的最初版已經(jīng)可以運行了。
是的,花費很少的功夫,一個簡單的POJOs,外加執(zhí)行“updateSchema”。接下來就是看看結(jié)果了。
OpenXava的結(jié)果
開發(fā)成果如下:
看,在這里用戶可以創(chuàng)建,更新,刪除,從列表生成PDF,將列表導(dǎo)出至excel,按單獨列排序,對過長列表進行分頁,以及數(shù)據(jù)的過濾。而且,無需任何代碼,只需執(zhí)行一個ant target,你便可以將應(yīng)用部署在JSR-168的portal中,而且OpenXava的portlet在感官上與這個portal是一致的。
這里,***生成,便得到足以投入生產(chǎn)的應(yīng)用。
少干活,得到細(xì)致的結(jié)果。
從哲學(xué)的角度來看,RoR與OX的差別就在于,在RoR中先寫表格,OpenXava中先寫類。
#p#
控制器
Rails已經(jīng)生成了用于最基本的CRUD的控制器邏輯如下:
另一方面,OX并沒有為CRUD生成任何代碼。OpenXava只有一個泛型的用于CRUD和Printing的代碼,這段代碼自動指定到所有的實體上。你可以自己編寫泛型CRUD邏輯,或者為某個實體編寫特定的邏輯,但是一個用于每個實體的控制器代碼是沒有的。這種情況下,需要維護的代碼量減少了,而你可以通過修改一處的代碼來實現(xiàn)所有CRUD模塊邏輯的改動。
也就是說,對于控制器,Rails使用生成代碼,而OX使用泛型代碼。
添加關(guān)系
要添加食譜與類別之間的關(guān)系,在Ruby下需要在category.rb中寫入以下代碼:
同時在recipe.rb中寫下下段代碼:
是的,相當(dāng)簡單。不過還有活兒要做。你需要編輯cookbook2\app\views\recipe\_form.rhtml,加入如下代碼:
﹤p﹥﹤label |
結(jié)果如下:
在OpenXava中,則需要用JPA在Category.java中定義如下關(guān)系:
@ManyToOne(optional=false) @DescriptionsList |
下面是Recipe.java的:
@OneToMany(mappedBy="category") |
HTML就不用改了。應(yīng)用看起來是這個效果:
從這里有鏈接通往修改及創(chuàng)建新類別的功能。
無需添加任何代碼,用戶在訪問類別模塊時便可以得到每個類別下的食譜列表,效果如下:
直至這里,RoR的應(yīng)用還沒有這個功能,為實現(xiàn)同樣的功能,還需要一些額外的Ruby和HTML代碼。
RoR和OX之間主要的區(qū)別在于,OX下無需編寫HTML代碼。事實上是,UI相關(guān)的代碼你一句都不用寫。
計算初始值
Ruby on Rails教程中的下一步,是生成一個屬性的初始值。RoR中,這是通過編輯控制器代碼來實現(xiàn)的。具體如下:
修改new以及update方法,添加下面這行代碼:
@recipe.date = Time.now |
相對應(yīng)的在OX中則是在模型中添加@DefaultValueCalculator注解:
@DefaultValueCalculator(CurrentDateCalculator.class) |
這樣,通過更加有說明性的方法實現(xiàn)了相同的效果。
也就是說,RoR中將代碼放入控制器中,OX下則把用于計算初始值,驗證以及商業(yè)邏輯的代碼放置在模型之中。OX提倡把商業(yè)邏輯從控制器中轉(zhuǎn)移至模型。
另外,純屬好奇:RoR那篇文章中說“修改了模型文件,所以我需要重啟web服務(wù)器?!笔褂肊clipse WTP時,我只需按下Ctrl-B,然后點擊瀏覽器中的刷新,便可以看到我在OpenXava應(yīng)用中修改模型的效果了。
結(jié)論
Ruby on Rails和OpenXava之間的主要區(qū)別在于RoR是一個MVC框架,你需要編寫模型,視圖及控制器。OX是一個模型驅(qū)動框架,你只需編寫模型。結(jié)果就是,用更少的代碼實現(xiàn)更好的應(yīng)用。
另一個很大的不同就是RoR使用被動的代碼生成;也就是說,它為你生成了代碼,但是之后想要擴展或修改的話則需要手動編輯。OpenXava不使用代碼生成,你有的代碼都是自己寫的。
在Java的宇宙間,你可以找到生產(chǎn)力。
原文:Java Kicks Ruby on Rails in the Butt by Javier Paniza
【編輯推薦】