Ruby vs Java 的幾個(gè)誤區(qū)
http://www.relevancellc.com/2007/6/2/ruby-vs-java-myth-1-project-size
圍繞Java與動(dòng)態(tài)語言(比如Ruby、PHP、Perl和Python)之間的爭論,雖然一直沒有一個(gè)確定的答案,但從來沒有消失過。隨著Java的日趨復(fù)雜,動(dòng)態(tài)語言的優(yōu)勢——簡化和易用就越加凸顯出來。.Ruby是一種好語言,和Rails一起提供了引人注目的新價(jià)值(從效率的角度)并且這樣的價(jià)值還在飛速地增長中。Ruby不一定是最好的語言,但是它也許會(huì)是最有可能挑戰(zhàn)Java的一種語言。它很有可能首先在一個(gè)更小但是卻重要的環(huán)境中取得好成績。
然而,在Ruby尚沒成為主流的今天,存在著關(guān)于Ruby對比Java而言而存在的若干誤區(qū),本文將通過對Ruby與Java兩種語言而來揭露這些誤區(qū)。
一、 誤區(qū)1:Ruby適合于小項(xiàng)目而Java適合于大型復(fù)雜項(xiàng)目
這種結(jié)論是非常的不切實(shí)際的。因?yàn)槭聦?shí)上,Java適合開發(fā)于小型且明確的項(xiàng)目,而Ruby反而適合于開發(fā)大型、復(fù)雜及開放性的項(xiàng)目。
Java適合小項(xiàng)目的理由如下:
1. 對于小項(xiàng)目,能找到一些開源且合適的內(nèi)庫,將意味著完成了十之八九了。這樣的開發(fā)模型效率最高。而Java提供的內(nèi)庫比任何語言都豐富;
2. 小項(xiàng)目的經(jīng)濟(jì)預(yù)算對于開發(fā)語言的不穩(wěn)定很敏感,希望越成熟越好。而Java語言眾所周知,而且開發(fā)文檔完備;
3. 對于小型項(xiàng)目,開發(fā)團(tuán)隊(duì)沒有足夠的時(shí)間與財(cái)力來學(xué)習(xí)新的語言,而Java則是大家都很熟悉的開發(fā)語言。
而對大型項(xiàng)目,Ruby則更有優(yōu)勢:
1. 由于大型項(xiàng)目的開發(fā)難度與任務(wù)艱巨,因此語言的開發(fā)效率比語言內(nèi)庫的多少顯得更加的重要。而Ruby正是這樣一種高效的開發(fā)語言;
2. 大項(xiàng)目肯定有許多意想不到的事情,因此對于這種變化,要求開發(fā)語言有極好的靈活性。而Ruby的靈活性是很好的;
3. 對于大型項(xiàng)目,技術(shù)培訓(xùn)將顯得很有遠(yuǎn)見。但很多公司都低估了這一點(diǎn)。大約5天的技術(shù)培訓(xùn),可以提高開發(fā)人員約10% 的開發(fā)效率,同時(shí),這種培訓(xùn)效果將保持在一年內(nèi)。Ruby正好適合這樣技術(shù)長遠(yuǎn)的培訓(xùn)。
那么,如果上面的神話如此的不切實(shí)際,人們?yōu)槭裁催€會(huì)相信呢?因?yàn)榈侥壳盀橹梗?/span>Ruby非常成功的應(yīng)用于一類小型項(xiàng)目的開發(fā):基于數(shù)據(jù)庫的web應(yīng)用程序。而Ruby on Rails的出現(xiàn)正好彌補(bǔ)了Ruby在開發(fā)小型項(xiàng)目方面的不足:
1. Rails正是人們所需要的庫;
2. Rails盡量排除小型項(xiàng)目的不穩(wěn)定性;
3. Rails有廣泛的實(shí)際經(jīng)驗(yàn),開發(fā)人員需要額外培訓(xùn)很少。
人們認(rèn)識(shí)到了Ruby on Rails的成功,于是由于思維定勢,只看到眾多小型成功的Ruby on Rails項(xiàng)目,眾多大型成功的Java項(xiàng)目,而沒有全面的了解實(shí)際的情況。從而就有了上面的認(rèn)識(shí)誤區(qū)。
二、 誤區(qū)2:Ruby特性會(huì)降低代碼的可維護(hù)性
Ruby的特性很多,如能寫出快速簡便的特性,動(dòng)態(tài)調(diào)用(dynamic evaluation),支持軟件封裝規(guī)則(soft encapsulation rules),簡易的元編程性(easy metaprogramming)及閉包性(closures)。盡管這些特性很不錯(cuò),但很多初學(xué)者常常擔(dān)心會(huì)降低代碼的可維護(hù)性。
事實(shí)上,Ruby豐富的特性如果使用得當(dāng)?shù)脑挘瑢⑻岣叽a的可維護(hù)性。那么提高可維護(hù)性標(biāo)準(zhǔn)是什么呢?
1. 提高整個(gè)程序或模塊的可理解性;
2. 易于查找代碼;
3. 提高代碼的可讀性;
4. 提高代碼的可修改性;
5. 方便修改過的代碼進(jìn)行回歸測試。
筆者認(rèn)為,程序開發(fā)人員應(yīng)用對軟件的可維護(hù)性負(fù)80%的責(zé)任,而只有20%的責(zé)任是由語言及工具來承擔(dān)。那么,讓我們逐條來看看Java和Ruby兩種語言,誰真正做到了上面提到的哪些標(biāo)準(zhǔn)吧。
提高整個(gè)程序或模塊的可理解性:兩者都可以。Java和Ruby其實(shí)有很多共同的點(diǎn):類、繼承性、多態(tài)性、封裝性等。而Java對這些抽象的共同有更好的支持與實(shí)現(xiàn),這主要是通過它的IDE來展現(xiàn),如IntelliJ IDEA。而Ruby則在結(jié)構(gòu)上更勝Java一籌。則Ruby則更加容易創(chuàng)建DSLs (Domain Specific Languages,領(lǐng)域特定語言),從而能較好的反映與描寫程序的設(shè)計(jì)思路。其實(shí),只有將Java與Ruby各自的特點(diǎn)疊加起來才能真正的提高整個(gè)程序或模塊的可理解性。
易于查找代碼:Java在這方面做得比較成功。它的IDE為它贏得了這一局。
提高代碼的可讀性:Ruby勝。就單個(gè)的類文件與方法這個(gè)層面來講,Ruby編寫的代碼能更容易保持簡潔性與可讀性。如果對些有疑問的話,可以在Blub paradox了解更多的這方面的信息。
提高代碼的可修改性:Ruby表現(xiàn)理佳。當(dāng)需要修改代碼時(shí),代碼維護(hù)人員經(jīng)常丟棄程序最初設(shè)計(jì)者的初衷。而一旦當(dāng)最初設(shè)計(jì)者的假設(shè)發(fā)生變化或被打破之后,編譯器在編譯的時(shí)候就會(huì)碰到問題。此時(shí),Ruby做為一種動(dòng)態(tài)語言,在這方面的優(yōu)勢就顯露出來了。
方便修改過的代碼進(jìn)行回歸測試:兩者都可以。測試是軟件開發(fā)必不可少的環(huán)節(jié)。如果僅僅是采用手工測試的話,則工作量太大,不切實(shí)際。因此可以采用一些自動(dòng)化的測試,如進(jìn)行單元測試、集成測試等。可喜的是,Java和Ruby都支持了自動(dòng)化的測試。
三、 誤區(qū)3:Ruby太難學(xué)習(xí)
很多人都認(rèn)為,Ruby對于一般的開發(fā)人員,其學(xué)習(xí)曲線比較難。其實(shí)這樣的結(jié)論是很有問題的:
1. 編程本身并不簡單。21天學(xué)會(huì)編程這樣的言論無異于天方夜譚。也許學(xué)習(xí)編程語言本身是一條比較平緩的曲線,但是,任何語言中的難題都需要痛苦的思考才能解決的。
2. “這太難了”在任何領(lǐng)域都不能成為不學(xué)習(xí)的借口。如果哪一家銀行漂亮的營業(yè)員說,我們只重復(fù)的使用加法來進(jìn)行計(jì)算,因?yàn)槌朔▽ξ覀兊某跫墕T工太難了,那還有誰會(huì)去這里辦理金融業(yè)務(wù)呢?如果一個(gè)外科醫(yī)生說,我就差10來年就退休了,所以也不用再學(xué)習(xí)新技術(shù)來改進(jìn)我的手術(shù)了,那么大家又做何想法呢?
3. Java跟Ruby一樣的難學(xué)。筆者經(jīng)常聽到這樣的言論:“Java里的反射機(jī)制我從來不用,因?yàn)樗y搞定了。”
4. 不能通過砍掉語言的特性來降低語言的學(xué)習(xí)難度。如果某種語言缺少開發(fā)人員所需要的某一特性,自持技術(shù)高深的牛人就會(huì)自己開發(fā)類型的特性。對小型項(xiàng)目而言,如果開始沒有使用程序塊,也許可以通過匿名內(nèi)部類來實(shí)現(xiàn)。對中型項(xiàng)目,可能要用到設(shè)計(jì)模式來實(shí)現(xiàn)。而對大型項(xiàng)目,一開始就使用實(shí)際意義不大的方式來構(gòu)建動(dòng)態(tài)的系統(tǒng),那到結(jié)果就是有可能產(chǎn)生一個(gè)巨大的框架,同時(shí)需要第二種語言來進(jìn)行冗長且易錯(cuò)的配置。
Java企業(yè)級框架很多而很著名,但其中過半的代碼存在很多的局限性,至少在語言層面是這樣。很多精明的Java開發(fā)人員為當(dāng)初“Java語言易于學(xué)習(xí)”的言論所忽悠,一直到后來才發(fā)現(xiàn)Java的學(xué)習(xí)曲線很復(fù)雜。
學(xué)習(xí)Java的學(xué)費(fèi)已經(jīng)交過了,那么Java當(dāng)然應(yīng)該好好的發(fā)揮作用了。所以Java社區(qū)的開發(fā)人員應(yīng)該為那么多優(yōu)秀的Java代碼感到自豪,盡管當(dāng)初學(xué)習(xí)開發(fā)Java的代價(jià)很大。
那么,Java開發(fā)人員就能過河拆橋嗎?如今輪到Ruby了,就說Ruby太難了?
四、 誤區(qū)4:Rails的思想很容易被復(fù)制
不管是Rails的狂熱粉絲,還是Rails的憤青們,都有一個(gè)共識(shí):Rails在Web開發(fā)具有很多閃光點(diǎn),于是很多其它的框架也開始Rials化了。既然我使用的Java開發(fā)框架已經(jīng)有了Rails的思想了,那為何還需關(guān)注Rails它本身呢?
很少有其他語言可以完成Rails,或者像Rails那樣的。Java不在他們之列。Rails從Ruby中獲取了一些妙不可言的東西,嘗試用另一種語言復(fù)制它不僅是對Rails所做的是一個(gè)浪費(fèi),對其他語言來說也是一個(gè)浪費(fèi)。但是它的概念一定會(huì)在其他非常動(dòng)態(tài)的,動(dòng)態(tài)類型語言中得到很好的應(yīng)用。如果將Rails的思想復(fù)制進(jìn)Java中,那么Rails的價(jià)值會(huì)大打折扣。而且如果對Rails了解不夠的話,那丟失了什么東西都還不知道呢。
Open classes特性允許擴(kuò)展類的定義,既可以擴(kuò)展整個(gè)類,也可以擴(kuò)展某個(gè)實(shí)例,Cool。
Rails使用open classes特性來構(gòu)建更加可讀的對象模型。例如,可以使用x.black?來代替StringUtilities.isBank(x)。當(dāng)然,如果只是一個(gè)這樣的取代并不能緊,但成百上千的使用,則可以大大的提高代碼的可讀性。
Open classes更重要的應(yīng)用是創(chuàng)建簡單的DSLs(領(lǐng)域特定語言),例如ActiveRecord所宣稱的關(guān)系與驗(yàn)證:
class Poet < ActiveRecord::Base
has_many :poems
validates_presence_of :name
end
DSLs經(jīng)常兩度的用到open classes特性,首先使用open classes來創(chuàng)建新的聲明“statements”,并符合類的聲明方式。第二,使用open classes來添加新的方法。當(dāng)然也可以使用Java Annotations來模擬實(shí)現(xiàn),但工作量巨大。這可以從Rails驗(yàn)證的代碼與采用Hibernate或Spring驗(yàn)證的代碼來進(jìn)行比較,就可以發(fā)現(xiàn)這種工作量的巨大性。
當(dāng)然,Rails的爭議還是有的。Rails的憤青們認(rèn)為,Rails的優(yōu)點(diǎn)只有在Ruby中才能體現(xiàn),而在Java則成為劣勢。例如,Java web應(yīng)用將業(yè)務(wù)邏輯與持久層進(jìn)行嚴(yán)格的分離,這對Java是很好的,除非應(yīng)用程序變化。而Rails對這種分離進(jìn)行了放棄,著重強(qiáng)調(diào)開發(fā)與配置的簡易性。這在Ruby環(huán)境下是很好的思想,因?yàn)殚_發(fā)人員可以隨時(shí)添加這個(gè)分離層。
當(dāng)然,不能用Java來實(shí)現(xiàn)Rails,卻并不意味著不能用Java做一些同樣優(yōu)秀的東西。Java的力量可以以一種有趣的、神奇的方式應(yīng)用到一種全新的框架上。只是還沒人做那些事情。每個(gè)人都對J2EE這個(gè)糕點(diǎn)趨之若騖,以至于沒人以一種更加激烈、更加動(dòng)態(tài)的方式來重新考慮問題。盡管有人提出一個(gè)基于Java的殺手級框架可以與Rails做同樣多工作, 它一定也不能做的象Rails一樣。
五、 結(jié)論:這是一場走向大同的游戲
Ruby是一種優(yōu)秀的開發(fā)語言,而Java是一個(gè)優(yōu)秀的平臺(tái)。如果讓Ruby運(yùn)行在Java的虛擬機(jī)上,則魚與熊掌可兼得也。
筆者認(rèn)為,做為一種開發(fā)語言開發(fā)普通的任務(wù),Ruby是優(yōu)于Java的;而做為一種平臺(tái),Java則更勝一籌。因?yàn)?/span>Ruby的運(yùn)行平臺(tái)是簡單的解釋執(zhí)行(MRI)。通過研讀Java平臺(tái)的源代碼,可以發(fā)現(xiàn)它確實(shí)是一種優(yōu)秀的平臺(tái),這表現(xiàn)在:
1. 字節(jié)碼指令集;
2. 簡便的類文件格式;
3. 強(qiáng)大的線程支持;
4. 十分安全的模型;
5. 眾多實(shí)踐過的部署方案;
難道就不能進(jìn)行有效的整合,構(gòu)建一個(gè)和諧程序世界?筆者不希望以出身論英雄,不要以開發(fā)語言來定位開發(fā)人員。而是希望可以采用Ruby、Scheme、Scala或Erlang來編寫優(yōu)秀的程序,但都可以和諧的運(yùn)行在Java的JVM上。
JRuby則是一個(gè)100%的Ruby編程語言的純Java實(shí)現(xiàn),這種語言在CPL,GPL和LGPL三種開源許可下發(fā)行。它是一個(gè)
JRuby允許現(xiàn)有Java開發(fā)者充分利用Ruby提供的強(qiáng)有力和易于使用的編程特點(diǎn),而Ruby開發(fā)者將能夠自由使用龐大的曾使Java廣泛地應(yīng)用于各個(gè)軟件開發(fā)領(lǐng)域的Java庫來進(jìn)行開發(fā)。
如果讀者想在這方面了解更多,那么下面的建議可能最有用:
1. JRuby項(xiàng)目;
2. 使用JRuby來編寫接下來的部分Java應(yīng)用。
3. 采用rake來代替ant管理Java應(yīng)用程序;
4. 對JRuby代碼進(jìn)行單元測試:Test:Unit。