轉眼2017,首先在這里祝您雞年大吉/*吧*/。
回想初到南京那會,15年夏天,還是抱著換換口味想要新鮮感的心情加入了現(xiàn)在這家創(chuàng)業(yè)公司。剛擺脫了一團亂麻一般的代碼的我心情愉悅,工作學習特別帶勁,一個禮拜能做十幾個feature。然而現(xiàn)在看看自己過去十幾個月里參與的項目。。只是一團稍顯整齊的亂麻而已,終究還是亂麻。
我可以說我編寫的代碼依舊遵守著我給它們的秩序,但是你沒法指望別人都這么做,同樣別人也沒法指望我那么做。盡管我在修改前人所寫的代碼的時候極力保持了同樣的風格,但是如果前人壓根就沒考慮過可擴展性以及高復雜度下的可讀性——比如一個if else塊300多行,你再怎么保持都沒用。給臭的東西噴香水只會讓味道變得更惡心。
一般在這個時候我們都會說,該重構了。沒錯,每個工作日我內心都有100個聲音在說重構吧重構吧。道理我都懂,但是看著越來越近的deadline和還沒做完的二十幾個feature,實在是沒有底氣和領導說我能在保證新功能測試時間的前提下完成重構,老板也不會在我們說要把新功能放一放先做點看不出效果的重構以后給我們好臉色看。
是的,有種陷入惡性循環(huán)的感覺。假如我是我領導,現(xiàn)在應該挺騎虎難下的。
為了有更直觀的感受,先來說說我們主站項目里幾個大概的數(shù)字吧。
客戶操作(如關注購買等)api數(shù): 100-200
客戶操作api的文件數(shù):5個左右
上述文件中最大一個的代碼行數(shù):30k行以上
上述文件中class數(shù):0
如果讓一個其他公司的同行來做代碼審查,過程中罵出的臟話估計夠把全上海人都罵一遍。
但是我們不知道這是不對的嗎?不,我們知道,我們清楚的知道,這也是我在15年為公司做的內部系統(tǒng)里采取完全不同設計的主要原因——舊代碼太亂了,我想看得清楚一點。但是為什么我們明明知道但是沒有去做呢?
測試,測試,測試。重要的話說三遍,我們沒有足夠的測試覆蓋率,因此也就沒法保證重構的效率。我不知道我同事沒有去做的原因是什么,反正我自己每每要嘗試重構的時候,測試這兩個字都像是在我面前的攔路猛虎。或許這與領導的風格有關,團隊最初建立的4個月里我沒有參與到,在我加入時大家對測試的要求都是自己測一測,保證功能沒問題就趕緊投入到下一個功能里。現(xiàn)在想想,我真是欠我的代碼,我的領導,看這篇文章的所有人,以及我自己一個大大的道歉。我的前一份工作是一個測試難度頗大的項目,UI代碼和AI代碼都是難以編碼測試或是依賴太多外部條件沒法確定明確的輸入輸出的,多數(shù)也都是跑一下看看沒問題就過了。于是我也就把這份慣性思維帶進了網(wǎng)站后臺的開發(fā)里。犯了如此愚蠢的錯誤真是對不起,讓你們瞎眼睛了。
畢業(yè)之初,我對測試的概念還是在保證功能正確無誤的工作的程度。但你現(xiàn)在要我說的話,測試不僅僅是保證你所寫的代碼正確無誤,這也是日后給你自己,你同事,接替你代碼的人的一份重要保證,是你敢修改代碼的底氣。不知道大家是否有犯過這樣的嘀咕:我改了這里以后會不會出BUG?我也經(jīng)常會這么問自己,當別人問我改完會對舊功能造成影響嗎?我往往需要深思熟慮一番,把這段代碼的各個調用點都找出來核對一下才敢給出確定的回復。
這番體會在有些人看來估計會很幼稚。沒錯,在我想明白之后我也覺得很幼稚,以往看過各種大牛的文章,沒有一個人說測試不重要的,然而卻花了我這么久才有自己的體會,真是難為情。不過這同時也引出了另一個問題,有了測試就萬無一失嗎?或者換個方式,要怎樣做測試才能萬無一失呢?
知乎有句話叫拋開劑量談毒性都是耍流氓,我們在談重構和測試的時候,拋開編碼也是耍流氓。在寫代碼的時候我們就要秉持著“可測試”的模式而去。什么叫可測試的模式呢?就是精簡模塊與單一功能。這概念很多年前就被說爛了,但是隨著閱歷增加每年都能有新的體會。前面說我在寫內部系統(tǒng)的時候采用了完全不同的設計也是使用了這個思路。主站項目里一個大類的所有模塊都揉在了一起。比如客戶端相關的功能就全都在同一個叫Customer的app下,后臺邏輯全都在同一個views里(沒錯就那個30k行的)。而內部系統(tǒng)采用了一個模塊一個app的設計,例如客服-反饋管理一個模塊,客服-訂單管理一個模塊,財務-退款審核一個模塊等等。這么做的好處是每次你打開一個文件,你所需要考慮的只有極少的事情,從而可以提高做事效率。同時保證模塊里每一個小函數(shù)都只做一件事情,這樣就又免去了不小心動到其他功能代碼的困擾,同時,測試代碼寫起來很方便。所以說好的編碼可以幫你做出好的測試。
內部系統(tǒng)持續(xù)迭代了一年多,到目前我驚訝的發(fā)現(xiàn)沒有重構的必要。因為各個模塊都分得很清楚,也很細。但是,事情總有個但是,模塊分得太細了導致其他同事認為不管新增什么功能都要新增一個app。舉個例子,現(xiàn)在線上活動越來越多了,我有專門建立過一個app來處理各類活動——因為活動是有時限性的,通常做過一次就不會再需要了,所以可以放一起。但是當某一天我同步了其他同事的提交后我還是無語了,他也新建了一個app專門處理17年新春活動。但這不是主要的,反正活動結束了把代碼歸檔就好了。更主要的是,他雖然模仿了我的風格,但是沒有理解我的意圖。就在那一刻我意識到了以后還可能出現(xiàn)元宵節(jié)活動,情人節(jié)活動,展館A活動,展館B活動等等大大小小的活動,都以一個app的形式出現(xiàn)在項目根目錄里,而不是我最初用來處理活動的app里。我不禁背后感到一絲涼意,雖然這件事和同事溝通一下就可以了,但是讓我感到恐慌的是今天是我同事,明天可能就是我了。我修改舊代碼時雖然極力保持了一致的風格,但那也只是我認為的風格,而對于整個項目來說這樣真的無害嗎?我是在幫助整個項目更有序化還是更無序化了呢?
或許這需要更高層的把控,每隔一段時間就要對整個項目做一次評估來確定重構的規(guī)模。但是,這世界上怎么這么多但是,重構前也要考慮這些時間花下去是不是劃算?曾經(jīng)和領導交談的時候有說過,對于穩(wěn)定而陳舊的代碼是否真有重構的必要?長時間下來都是小修小改,重構完也只不過是讓我們自己看著舒服罷了,對于非技術出身的老板來說重構更是一件吃力不討好的事情。花了時間,取得了什么效果嗎?有效果,但是看不出來 = 沒效果。當然作為程序員我們比任何人都清楚重構的重要性,但是我們不能眼里只有技術。
十幾個月的過程感受下來,程序員還是要有對技術之外的理解,比如商業(yè)需求之類的。有時候運營人員或者是PM來和我們談需求的時候,我們認為的愚蠢需求其實是有其商業(yè)價值的,只不過對方在轉化的時候沒能幫我們解釋清楚,到最后我們的一句做不了或是沒意義可能就錯失了機會,尤其是對于一個運營不成熟的團隊。對于系統(tǒng)的理解我們是高過他們的,但是對于用戶的理解,還是要相信他們的判斷。
羅羅嗦嗦一大堆,自己都覺得自己太怨天尤人了。程序員還是要做實干派,有問題就要解決,有BUG就要修,不能單單紙上談兵。希望2017能讓自己成為一個更優(yōu)秀的人,年后要考慮回上海工作了,相比15年走的時候我有沒有變更好呢?
世界太廣太大,我連好的邊緣都夠不上。只有那一畝三分地,略有收獲而已。