轉(zhuǎn)眼2017,首先在這里祝您雞年大吉/*吧*/闹蒜。
回想初到南京那會寺枉,15年夏天,還是抱著換換口味想要新鮮感的心情加入了現(xiàn)在這家創(chuàng)業(yè)公司绷落。剛擺脫了一團(tuán)亂麻一般的代碼的我心情愉悅姥闪,工作學(xué)習(xí)特別帶勁,一個禮拜能做十幾個feature砌烁。然而現(xiàn)在看看自己過去十幾個月里參與的項目甘畅。。只是一團(tuán)稍顯整齊的亂麻而已往弓,終究還是亂麻疏唾。
我可以說我編寫的代碼依舊遵守著我給它們的秩序,但是你沒法指望別人都這么做函似,同樣別人也沒法指望我那么做槐脏。盡管我在修改前人所寫的代碼的時候極力保持了同樣的風(fēng)格,但是如果前人壓根就沒考慮過可擴(kuò)展性以及高復(fù)雜度下的可讀性——比如一個if else塊300多行撇寞,你再怎么保持都沒用顿天。給臭的東西噴香水只會讓味道變得更惡心堂氯。
一般在這個時候我們都會說,該重構(gòu)了牌废。沒錯咽白,每個工作日我內(nèi)心都有100個聲音在說重構(gòu)吧重構(gòu)吧。道理我都懂鸟缕,但是看著越來越近的deadline和還沒做完的二十幾個feature晶框,實在是沒有底氣和領(lǐng)導(dǎo)說我能在保證新功能測試時間的前提下完成重構(gòu),老板也不會在我們說要把新功能放一放先做點看不出效果的重構(gòu)以后給我們好臉色看懂从。
是的授段,有種陷入惡性循環(huán)的感覺。假如我是我領(lǐng)導(dǎo)番甩,現(xiàn)在應(yīng)該挺騎虎難下的侵贵。
為了有更直觀的感受,先來說說我們主站項目里幾個大概的數(shù)字吧缘薛。
客戶操作(如關(guān)注購買等)api數(shù): 100-200
客戶操作api的文件數(shù):5個左右
上述文件中最大一個的代碼行數(shù):30k行以上
上述文件中class數(shù):0
如果讓一個其他公司的同行來做代碼審查窍育,過程中罵出的臟話估計夠把全上海人都罵一遍。
但是我們不知道這是不對的嗎宴胧?不蔫骂,我們知道,我們清楚的知道牺汤,這也是我在15年為公司做的內(nèi)部系統(tǒng)里采取完全不同設(shè)計的主要原因——舊代碼太亂了,我想看得清楚一點浩嫌。但是為什么我們明明知道但是沒有去做呢檐迟?
測試,測試码耐,測試追迟。重要的話說三遍,我們沒有足夠的測試覆蓋率骚腥,因此也就沒法保證重構(gòu)的效率敦间。我不知道我同事沒有去做的原因是什么,反正我自己每每要嘗試重構(gòu)的時候束铭,測試這兩個字都像是在我面前的攔路猛虎廓块。或許這與領(lǐng)導(dǎo)的風(fēng)格有關(guān)契沫,團(tuán)隊最初建立的4個月里我沒有參與到带猴,在我加入時大家對測試的要求都是自己測一測,保證功能沒問題就趕緊投入到下一個功能里⌒竿颍現(xiàn)在想想拴清,我真是欠我的代碼靶病,我的領(lǐng)導(dǎo),看這篇文章的所有人口予,以及我自己一個大大的道歉娄周。我的前一份工作是一個測試難度頗大的項目,UI代碼和AI代碼都是難以編碼測試或是依賴太多外部條件沒法確定明確的輸入輸出的沪停,多數(shù)也都是跑一下看看沒問題就過了煤辨。于是我也就把這份慣性思維帶進(jìn)了網(wǎng)站后臺的開發(fā)里。犯了如此愚蠢的錯誤真是對不起牙甫,讓你們瞎眼睛了掷酗。
畢業(yè)之初,我對測試的概念還是在保證功能正確無誤的工作的程度窟哺。但你現(xiàn)在要我說的話泻轰,測試不僅僅是保證你所寫的代碼正確無誤,這也是日后給你自己且轨,你同事浮声,接替你代碼的人的一份重要保證,是你敢修改代碼的底氣旋奢。不知道大家是否有犯過這樣的嘀咕:我改了這里以后會不會出BUG泳挥?我也經(jīng)常會這么問自己,當(dāng)別人問我改完會對舊功能造成影響嗎至朗?我往往需要深思熟慮一番屉符,把這段代碼的各個調(diào)用點都找出來核對一下才敢給出確定的回復(fù)。
這番體會在有些人看來估計會很幼稚锹引。沒錯矗钟,在我想明白之后我也覺得很幼稚,以往看過各種大牛的文章嫌变,沒有一個人說測試不重要的吨艇,然而卻花了我這么久才有自己的體會,真是難為情腾啥。不過這同時也引出了另一個問題东涡,有了測試就萬無一失嗎?或者換個方式倘待,要怎樣做測試才能萬無一失呢疮跑?
知乎有句話叫拋開劑量談毒性都是耍流氓,我們在談重構(gòu)和測試的時候凸舵,拋開編碼也是耍流氓祸挪。在寫代碼的時候我們就要秉持著“可測試”的模式而去。什么叫可測試的模式呢贞间?就是精簡模塊與單一功能贿条。這概念很多年前就被說爛了雹仿,但是隨著閱歷增加每年都能有新的體會。前面說我在寫內(nèi)部系統(tǒng)的時候采用了完全不同的設(shè)計也是使用了這個思路整以。主站項目里一個大類的所有模塊都揉在了一起胧辽。比如客戶端相關(guān)的功能就全都在同一個叫Customer的app下,后臺邏輯全都在同一個views里(沒錯就那個30k行的)公黑。而內(nèi)部系統(tǒng)采用了一個模塊一個app的設(shè)計邑商,例如客服-反饋管理一個模塊,客服-訂單管理一個模塊凡蚜,財務(wù)-退款審核一個模塊等等人断。這么做的好處是每次你打開一個文件,你所需要考慮的只有極少的事情朝蜘,從而可以提高做事效率恶迈。同時保證模塊里每一個小函數(shù)都只做一件事情,這樣就又免去了不小心動到其他功能代碼的困擾谱醇,同時暇仲,測試代碼寫起來很方便。所以說好的編碼可以幫你做出好的測試副渴。
內(nèi)部系統(tǒng)持續(xù)迭代了一年多奈附,到目前我驚訝的發(fā)現(xiàn)沒有重構(gòu)的必要。因為各個模塊都分得很清楚煮剧,也很細(xì)斥滤。但是,事情總有個但是勉盅,模塊分得太細(xì)了導(dǎo)致其他同事認(rèn)為不管新增什么功能都要新增一個app佑颇。舉個例子,現(xiàn)在線上活動越來越多了菇篡,我有專門建立過一個app來處理各類活動——因為活動是有時限性的,通常做過一次就不會再需要了一喘,所以可以放一起驱还。但是當(dāng)某一天我同步了其他同事的提交后我還是無語了,他也新建了一個app專門處理17年新春活動凸克。但這不是主要的议蟆,反正活動結(jié)束了把代碼歸檔就好了。更主要的是萎战,他雖然模仿了我的風(fēng)格咐容,但是沒有理解我的意圖。就在那一刻我意識到了以后還可能出現(xiàn)元宵節(jié)活動蚂维,情人節(jié)活動戳粒,展館A活動路狮,展館B活動等等大大小小的活動,都以一個app的形式出現(xiàn)在項目根目錄里蔚约,而不是我最初用來處理活動的app里奄妨。我不禁背后感到一絲涼意,雖然這件事和同事溝通一下就可以了苹祟,但是讓我感到恐慌的是今天是我同事砸抛,明天可能就是我了。我修改舊代碼時雖然極力保持了一致的風(fēng)格树枫,但那也只是我認(rèn)為的風(fēng)格直焙,而對于整個項目來說這樣真的無害嗎?我是在幫助整個項目更有序化還是更無序化了呢砂轻?
或許這需要更高層的把控奔誓,每隔一段時間就要對整個項目做一次評估來確定重構(gòu)的規(guī)模。但是舔清,這世界上怎么這么多但是丝里,重構(gòu)前也要考慮這些時間花下去是不是劃算?曾經(jīng)和領(lǐng)導(dǎo)交談的時候有說過体谒,對于穩(wěn)定而陳舊的代碼是否真有重構(gòu)的必要杯聚?長時間下來都是小修小改,重構(gòu)完也只不過是讓我們自己看著舒服罷了抒痒,對于非技術(shù)出身的老板來說重構(gòu)更是一件吃力不討好的事情幌绍。花了時間故响,取得了什么效果嗎傀广?有效果,但是看不出來 = 沒效果彩届。當(dāng)然作為程序員我們比任何人都清楚重構(gòu)的重要性伪冰,但是我們不能眼里只有技術(shù)。
十幾個月的過程感受下來樟蠕,程序員還是要有對技術(shù)之外的理解贮聂,比如商業(yè)需求之類的。有時候運營人員或者是PM來和我們談需求的時候寨辩,我們認(rèn)為的愚蠢需求其實是有其商業(yè)價值的吓懈,只不過對方在轉(zhuǎn)化的時候沒能幫我們解釋清楚,到最后我們的一句做不了或是沒意義可能就錯失了機(jī)會靡狞,尤其是對于一個運營不成熟的團(tuán)隊耻警。對于系統(tǒng)的理解我們是高過他們的,但是對于用戶的理解,還是要相信他們的判斷甘穿。
羅羅嗦嗦一大堆腮恩,自己都覺得自己太怨天尤人了。程序員還是要做實干派扒磁,有問題就要解決庆揪,有BUG就要修,不能單單紙上談兵妨托。希望2017能讓自己成為一個更優(yōu)秀的人缸榛,年后要考慮回上海工作了,相比15年走的時候我有沒有變更好呢兰伤?
世界太廣太大内颗,我連好的邊緣都夠不上。只有那一畝三分地敦腔,略有收獲而已均澳。