程序員之拍案驚奇:為什么我會一天到晚的想說FUCK!
經(jīng)常有人找我給他們的軟件項(xiàng)目做修改或維護(hù),我對這些項(xiàng)目毫不了解,而他們只告訴一些很少的項(xiàng)目相關(guān)信息。必然的,需要在項(xiàng)目中增加一些新的功能,但在動手之前,我通常需要耗費(fèi)大量的功夫來大幅度的重構(gòu)它們。
JavaScript (Photo credit: Johannes_wl)
大概一個月前,一個公司老板給我來信“嗨,我有一個軟件,需要做一些個性化的改動,有個大客戶愿意花一大筆錢來買它,正等著呢,可我現(xiàn)在都沒辦法讓它跑起來,最初的開發(fā)人員都找不到了。你能幫我搞定它嗎?”
最初的程序員的逃離已經(jīng)是亮起了紅燈,但這個項(xiàng)目的技術(shù)架構(gòu)正和我的胃口:node.js,mongodb,大量的事實(shí)數(shù)據(jù)流,以及UI上更新的速度要求。這個等待使用這個軟件的用戶的名字也讓我精神一振。
我干!能壞到哪去?
你會忍不住的想罵街
能壞到不能再壞。
項(xiàng)目的一部分是用Java寫成的。這很好,根據(jù)項(xiàng)目的現(xiàn)狀,選用靜態(tài)類型的語言是明智的選擇。
而其余部分是用Javascript寫的。Java和服務(wù)器端JavaScript和前端Javascript通信的機(jī)制是…..哇塞,這有個限制,參數(shù)名長度不能超過3個字符。
好吧,節(jié)省帶寬,不是嗎?我們現(xiàn)在說的這個項(xiàng)目具有巨大的數(shù)據(jù)流量,所以就盡量讓json對象保持最小體積吧。
這就是讓事情變得棘手的地方。
因?yàn)楹诵膫鬏攨f(xié)議里只讓各種變量名長3個字符,所以數(shù)據(jù)庫設(shè)計也遵照這個原則。因?yàn)閿?shù)據(jù)庫里的各種表名、字段名、視圖名等等都是這個模樣,你猜怎么著?沒錯!所有的程序代碼都沿襲了變量名不超過3個字符的特征。
這個風(fēng)俗的滲透超出了變量名進(jìn)而感染了數(shù)據(jù)。
為什么在應(yīng)該寫成label地方偏要寫成lbl呢?以及諸如此類,等等等等…..在差不多兩個月的研究這個項(xiàng)目后,我仍然不知道大部分的變量名的真實(shí)含義。我只是把它們當(dāng)作是拉丁語,用來描述一種模糊的概念。我開始對這個項(xiàng)目是如何運(yùn)轉(zhuǎn)的有了一些理解。
情況慢慢清晰起來。
如何讓一個布爾值符合這種命名機(jī)制?這樣做:
- function fix(boolean_value) {
- return boolean_value ? 'tru' : 'fls';
- }
好吧,但愿事情到此為止,但我發(fā)現(xiàn)了另外一個有趣的東西…這個東西在很多代碼里反復(fù)出現(xiàn),我不敢動它們,我怕會發(fā)生什么不可思議的事,會讓有些程序跑不起來。
我有沒有跟你們說過這個項(xiàng)目是沒有單元測試代碼的?當(dāng)發(fā)現(xiàn)需要給它們寫單元測試時你知道我有多受打擊嗎?但是,好在這個項(xiàng)目看起來最終不需要通過一個安全測試….哦,等一下,程序里有安全檢查代碼。
- if (!thing || thing === 'null') ...
起初我一直在寬慰自己說他們這樣做一定有必要的原因。
不管怎樣,我全忍受了,有些東西從某種角度看似乎是合理的,有些可能是過度優(yōu)化造成的。很糟糕,但有些我還是可以忍受的。
下面的這個是讓我真正抓狂的東西:
- function getPurple(cake) {
- cake.color = global_color_setting;
- return cake;
- }
我甚至不知道如何入手去重構(gòu)它,讓它變得有實(shí)際作用…完全就是…什么玩意?誰干的?。?/p>
然而,這最糟糕的事情,最最糟糕的事情是,這個項(xiàng)目不知從何時起由傳統(tǒng)的jQuery轉(zhuǎn)向了Backbone。這沒任何的問題,遷移的很好,我喜歡Backbone!
但他們忘了進(jìn)行徹底的遷移。很多時候Backbone只是一個很薄的皮,包著舊的東西。大部分的代碼甚至根本沒有使用Backbone,仍然使用大量的$.ajax,隨處可見。
在這樣一種弱類型化的語言、沒有單元測試代碼的情況下,我根本不可能說“嗨,我修改名稱X,請把相關(guān)的所有引用都改一下”…用grep命令搜索,也只能這樣了,我的這段日子過的太充實(shí)了。
不知道系統(tǒng)什么時候就會突然崩潰,因?yàn)槲乙餐巳y試…