|
英文原文:Your Code is My Hell
我最近的作為一個(gè)Rails程序員的經(jīng)歷可能并不常見(jiàn)。
我經(jīng)常被叫去維護(hù)一些已經(jīng)做好的Ruby/Rails項(xiàng)目,在力所能及的地方進(jìn)行改進(jìn)和完善。這樣,絕大部分我需要接手的項(xiàng)目在我出現(xiàn)前都已經(jīng)開(kāi)發(fā)完成了。事實(shí)上,在我的記憶里,我只參與了一個(gè)商業(yè)性質(zhì)的格林菲爾德Ruby項(xiàng)目的開(kāi)發(fā)。其它的,在我看來(lái),都是歷史遺物,相當(dāng)多的程序代碼在我之前都已經(jīng)出品了。(不包括個(gè)人和內(nèi)部項(xiàng)目)。
我知道,我的這種經(jīng)歷在Ruby和Rails程序員中并不常見(jiàn)。由于Ruby/Rails的高產(chǎn)和創(chuàng)業(yè)公司為主的用戶環(huán)境,大多數(shù)Ruby愛(ài)好者都是在這樣剛成立的公司里開(kāi)發(fā)全新的項(xiàng)目。而我的工作更多的是基于最初的開(kāi)發(fā)人員走后留下來(lái)的代碼。
Rails的讓人不堪的小秘密
在受雇寫(xiě)Ruby程序之前,我也接手過(guò)一些歷史程序,它們有的歷史達(dá)數(shù)十年之久,代碼量數(shù)十萬(wàn)行之多。你很容易在這么多代碼里找出寫(xiě)的很爛的東西;有時(shí)候,這種爛代碼的數(shù)量多的讓人驚訝。
但是,在Rails開(kāi)發(fā)中,你會(huì)發(fā)現(xiàn)一個(gè)讓人不堪忍受的小秘密;在我的職業(yè)生涯中,我見(jiàn)過(guò)的最亂的、最棘手的、最臭的代碼,都是在Ruby on Rails項(xiàng)目里找到的。我所見(jiàn)過(guò)的那些Rails項(xiàng)目,它們兩年下來(lái)積累的技術(shù)債務(wù)和廢棄物,跟一個(gè)10年之久的C/C++程序相比,會(huì)讓你覺(jué)得后者更干凈和優(yōu)雅。我說(shuō)的并不是某個(gè)項(xiàng)目。我看到這種情況到處都是。
有時(shí)候我會(huì)想,這也顯示了這種語(yǔ)言的強(qiáng)大之處。如果在一個(gè)Rails應(yīng)用里有500個(gè)錯(cuò)誤,你可以不停的往里面添加代碼、再添加代碼、點(diǎn)擊reload,一直到它好用為止。從來(lái)都不需要寫(xiě)測(cè)試或重構(gòu)代碼。在很多語(yǔ)言和框架里,這種補(bǔ)到它不漏為止的開(kāi)發(fā)方式顯而易見(jiàn)是行不通的。但Ruby on Rails卻提供了讓你這樣做的平臺(tái)。
不幸的是,作為它的直接后果,眾多我要處理的項(xiàng)目都可以被看作是一種應(yīng)急產(chǎn)品。從某種角度來(lái)看,這種圖省事的做法的后果還是由開(kāi)發(fā)團(tuán)隊(duì)來(lái)承擔(dān),你這樣做一天把它解決了,可引出的相關(guān)問(wèn)題和不可預(yù)料的副作用,你花2周都解決不掉。
題外話:經(jīng)常的,最初的開(kāi)發(fā)人員會(huì)在完成開(kāi)發(fā)后轉(zhuǎn)移到新的項(xiàng)目上。同時(shí)會(huì)有新員工接手這些代碼。管理部門(mén)會(huì)抱怨,為什么這新接手的團(tuán)隊(duì)修改問(wèn)題時(shí)沒(méi)有老團(tuán)隊(duì)迅速呢?而新團(tuán)隊(duì)遇到的問(wèn)題是,在他們能給這些遺留的代碼上添加新功能前,他們需要讓這些代碼具有更高的測(cè)試覆蓋率,有可能還需要把它們分離成更小的模塊;在商業(yè)層面,一個(gè)永久不變的聲音是:測(cè)試和重構(gòu)就是拖延工期。看來(lái)這原創(chuàng)團(tuán)隊(duì)都是比較明智的。
好了,牢騷發(fā)完了。
Rails的情況更為特殊!
Rails程序員有時(shí)候會(huì)顯得很傲慢和固執(zhí)。我不清楚這個(gè)判斷的可信度;我并沒(méi)有看到太多的人是這樣,但也許我跟這個(gè)社區(qū)太接近了,也許我本身也是傲慢和固執(zhí)的。
而我發(fā)現(xiàn)的卻是一種Rails例外主義。還記得第一次互聯(lián)網(wǎng)繁榮的時(shí)期嗎,當(dāng)時(shí)有幾個(gè)經(jīng)濟(jì)學(xué)家跳出來(lái)說(shuō)不會(huì)的,這次不同,互聯(lián)網(wǎng)改變了游戲規(guī)則,市場(chǎng)會(huì)一直走高、走高,本質(zhì)上我感覺(jué)很相似,有些人相信,Ruby on Rails開(kāi)發(fā)是某種不同的東西,不需要跟其它類型的軟件項(xiàng)目一樣。
這有一些例子,讓你明白我究竟在說(shuō)什么:
- 設(shè)計(jì)模式是Java上的東西。Ruby里只管寫(xiě)你的代碼就是了。
- Ruby里拋出的警告都是無(wú)聊的,禁止掉就行了。
- 的確沒(méi)有單元測(cè)試,而且對(duì)象隔離做起來(lái)了很難,沒(méi)有人這樣做。
- 到處打補(bǔ)丁對(duì)于其它語(yǔ)言來(lái)說(shuō)是不贊成的,但Ruby沒(méi)問(wèn)題。目前還沒(méi)有出現(xiàn)問(wèn)題。
- 像Demeter定律這樣的東西在Ruby里并不是這么重要。
- 把方法分成私有和公有,這是變態(tài)控制,Ruby里不需要這樣做
- Java代碼里才會(huì)有代碼異味(code smell)。
- 只有在大項(xiàng)目里才會(huì)有這樣的問(wèn)題(暗示這個(gè)項(xiàng)目永遠(yuǎn)不會(huì)變大)
我還看到了很多項(xiàng)目和子系統(tǒng)例外主義者:我知道一個(gè)類不應(yīng)該搞的太大,但是對(duì)這個(gè)類是有意義的,它是為了把所有的東西放到一個(gè)地方。
歡迎來(lái)到小人國(guó)
事實(shí)上,Ruby on Rails項(xiàng)目確實(shí)有一點(diǎn)很例外:都是小項(xiàng)目。上周在James Gray在Lone Star Ruby Conf大會(huì)上有個(gè)極好主題,他提到的巨型項(xiàng)目有4萬(wàn)多行代碼。這讓我微微一笑,因?yàn)槲冶还蛠?lái)做的頭兩個(gè)項(xiàng)目分別有5萬(wàn)行和7萬(wàn)行。這看起來(lái)不少,但根據(jù)行業(yè)標(biāo)準(zhǔn),它們很小。
造成這種現(xiàn)象的原因有不少。Ruby是一種比Java更富有表達(dá)性的語(yǔ)言,所以,從某種程度上說(shuō),Rails項(xiàng)目,在相同的情況下,總是比那些更講究的語(yǔ)言顯得更小。
而且,Rails程序員很喜歡接受把系統(tǒng)分割成很多很小的、相互聯(lián)系的小應(yīng)用。但是經(jīng)驗(yàn)告訴我們,這種策略是有問(wèn)題的。
不,我想這導(dǎo)致Rails應(yīng)用體格較小的最大的原因是,顯而易見(jiàn)的:這個(gè)框架還很年輕。這個(gè)領(lǐng)域里有大量不成熟的產(chǎn)品。一個(gè)Rails應(yīng)用如果有3年的歷史,那就可以算是古老了。
我可以很有信心的說(shuō),這種情況不會(huì)一直持續(xù)下去。我們會(huì)看到越來(lái)越大的程序項(xiàng)目。我不需要鼓起勇氣就可以做下面的預(yù)言:很多項(xiàng)目將會(huì)遭遇像Lisp, Smalltalk, C++, Java等語(yǔ)言曾經(jīng)遭遇過(guò)的相同的架構(gòu)瓶頸。
你并不特殊
《programming literature from the 80s》這個(gè)作品讀起來(lái)非常的有趣。動(dòng)態(tài),面向?qū)ο蟮南到y(tǒng)引導(dǎo)了從小規(guī)模到中等規(guī)模的過(guò)渡。聽(tīng)起來(lái)耳熟,是吧?
每一次的革命都會(huì)堅(jiān)稱這次是與眾不同的,不會(huì)造成上次革命后出現(xiàn)的政黨紛爭(zhēng)和官僚腐敗。起初你很容易被這些宣傳感染。每個(gè)人都很興奮,熱情的去幫助;這時(shí)出現(xiàn)的問(wèn)題還比較小;然而這只是市場(chǎng)的大機(jī)器還沒(méi)有注意到這場(chǎng)運(yùn)動(dòng)。
事實(shí)上,你要解決的問(wèn)題也許并不是你想像的那樣例外。你思想里的這種拜占庭模式只是遠(yuǎn)古時(shí)代那些使用跟Ruby類似語(yǔ)言的人留下來(lái)的遺產(chǎn)。
不要驚慌
放松。我這里要說(shuō)的并不是告訴你過(guò)去的幾年只是一場(chǎng)可愛(ài)的夢(mèng),Ruby實(shí)際上一直處在它應(yīng)有的地位上。
Ruby仍然是一種奇妙的語(yǔ)言,它令人驚異的地方就是它在付出微小的約束代價(jià)下能輕松的接納大型系統(tǒng)的設(shè)計(jì)模式。注入依賴??jī)簯颉?duì)象委托和組合?小菜一碟。跟你的錯(cuò)覺(jué)正好相反,Ruby并不拒絕嚴(yán)謹(jǐn)?shù)脑O(shè)計(jì)模式和SOLID編程原則;Ruby能做到的事是讓它們更容易的表達(dá)出來(lái)。事實(shí)上,Ruby強(qiáng)大的富于表達(dá)的架構(gòu)風(fēng)格是讓很多人第一眼就喜歡上它的原因。
拜托:請(qǐng)?jiān)谀愀嬖V我Ruby和Rails不需要任何的約束之前,請(qǐng)跟那些仍然在維護(hù)你當(dāng)初開(kāi)發(fā)的Rails應(yīng)用的兄弟們聊一聊。
it知識(shí)庫(kù):Rails程序員:你的代碼是我的地獄,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。