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
















 
 
 






 
 
 
 