如何維護可讀性很差的代碼?

最近加入了一個項目,嵌入式C語言開發,代碼量3萬6千行(.c/.h)。

這個項目之前基本是由一個同事開發的,沒有code review, 沒有高級工程師verify。

現在急著要上線過測試無法重構,而且bug很多。

這位同事現在被抽調去做別的項目,目前讓我接手bug修正。

可讀性差表現在:

命名英文拼音混雜,不少英文拼寫錯誤;

縮進(對齊)和空行亂用,大量條件編譯的代碼。

注釋與代碼邏輯不符,函數名與功能不符;

if和else if 中的條件關聯性相差非常大;

函數行數非常多(500-1000);

系統框架不是很好,有個輪詢線程與另一個模塊通信後刷新用戶界面設置(UI設置耦合輪詢你敢信?)等等。

面對類似以上的情況,如何使其往好的方向發展?希望大家能夠分享一些這方面的經驗。

(然而並不包括「換一家公司」: P )


謝邀。

3.6 萬行代碼不算多,如果策略得當,估計能在短期內搞定。

可讀性差表現在:
命名英文拼音混雜,不少英文拼寫錯誤;
縮進(對齊)和空行亂用,大量條件編譯的代碼。
注釋與代碼邏輯不符,函數名與功能不符;
if和else if 中的條件關聯性相差非常大;
函數行數非常多(500-1000);

感覺這像一位初級猿或者不稱職的中級猿所為。一個急著上線的項目,安排一個不靠譜的初級猿來做,bug 很多還沒 code review,這是哪位領導安排的?是不是腦洞有點狹窄?

現在急著要上線過測試無法重構,而且bug很多。

我的建議是:

1、Debug by tracing

既然急著上線是首要目標,那麼應該以調試(debugging)為主,先爭取幹掉大部分的 bug,保證現有程序能完好運行,通過主要的測試。

調試你的 C 程序首選 printf 大法,通過看 log 或 console 輸出來定位 bug。

2、Refactor with unit testing

對你來說,重構是一個相對次要的目標,可以在調試的過程中邊調邊改。先嘗試少量的手工重構,以後看能否借用自動重構工具。

Code refactoring

可靠的代碼重構是要由單元測試、集成測試等組成的(回歸)測試安全網來防護的。現在讓你把 C 程序的回歸測試補起來,時間不一定來得及。所以我說重構是次要目標,要小改不要大改,先把非改不可的地方改掉,讓程序先運行、測試通過,其他缺陷可以後有時間了再改。

最終是應該把單測環境建好的。C 的單測工具參考:

List of unit testing frameworks

以上我所說的是一種比較保守、穩妥的策略。考慮到你時間比較緊,急著上線。打個比方,這就像老房子裝修、翻新。老房子的整體結構、地基(架構)是原來的,只不過內外的裝修,某些局部結構、設施發生了變化,但整座房子經過翻新不僅可以照常使用,還可以滿足新的需求,效果也不錯。這適合原來代碼基本可用(如接近 50%)的情況。

另一種激進的維護策略是完全蓋一座新樓,地基、主體結構是全新的,在建新樓時可以把老房子里一些仍有利用價值的設備、物件等(函式或代碼)裝入新樓,加以重複利用。這適合老房子搖搖欲墜、確實很爛(如可用代碼 &< 30%)的情況。

。。。


  1. 拆分代碼,將比較長的代碼進行逐一拆分,保證每個函數的功能單一,寫上函數參數注釋。(看懂一個寫一個
  2. 結合項目的作用,使用printf列印出函數的主要脈絡。入口-&>中間層-&>出口。
  3. 項目主要脈絡出來以後,其實就很好維護了。繼續對函數進行拆分,注意,拆分之前一定要注意git的使用,如果出bug,馬上回滾。
  4. 一個項目之中,主要邏輯其實都不算很多,大部分的代碼屬於異常處理。異常處理這部分其實是最蛋疼的,一般出bug的地方也在這裡。記住:任何一行代碼都是為了解決某個場景所存在的。 我一般有兩個辦法,第一個就是去看測試,第二個就是printf了。
  5. 最後一個辦法,買一把菜刀,積攢一波不懂的,找到那個人,他不願意回答,你就拔出剛剛買的菜刀。

哪裡出錯跟著入口一步步走呀,面對一坨用坨來衡量的代碼花心思讀懂幹嘛,畫個草圖,他從哪個函數到哪個函數畫下來。要到bug測試用例走一遍完事了,你不需要修復bug。


推薦閱讀:

雷軍問我:你寫程序有寫詩一樣的感覺嗎?
哪種語言適合沒有編程經驗的人學習?
為什麼階乘一定是偶數?
作為一個有理想的程序員,必讀的書都有哪些?
為什麼軟體學院的學費那麼貴?

TAG:重構 | 編程 | 敏捷開發 | 嵌入式開發 | 軟體調試 |