談談程式碼重構

akiyama發表於2019-05-05

好久沒寫文章了,最近太忙了,詐個屍,恰好最近在程式碼重構,簡單談談什麼時候重構、重構的原則以及怎麼實施去重構。

什麼時候進行重構?

任何時間都可以進行重構,前提是你有足夠的時間以及精力去做這件事情,大部分公司重構程式碼是不會計入KPI的,甚至重構的越多,出bug的概率就越大,背鍋的可能就越大。因此,小規模的重構或者自己負責功能的重構,可以穿插在需求中進行;大規模重構因為耗費時間較長,出錯概率較高,必須要得到上級的支援才能進行下去。大規模重構的需求來源一般都是因為目前技術架構已經不能滿足快速的業務迭代,可維護性差,新人上手困難,出現bug機率增加,當程式碼已經到達這個程度的時候,就需要推進進行大規模重構了。

重構的原則

需要理清楚的是重構不是重寫,更不是解決bug,引入新需求。很多新手在進行重構的時候,往往會在重構過程中去修改之前的固有邏輯,甚至增加一些自己的業務理解去“優化”現有的程式碼,這是大錯特錯的,因此重構的第一個原則是:“忠於原始碼”,特別是在自己無法理解之前業務的下,儘量忠於原文,可以減少產生的新的bug,可測性增強。

重構的第二個原則:“逐步實施”。儘量不要一下子就推翻重建,應該從儘量底層去抽取共性,由點及面,分解目標,逐步實施;比如你要對當前程式碼做整體的MVP重估,這個時候你可以先把當前業務理清楚,分析核心業務,從最簡單的業務入手,保留原有的結構,逐步相容,然後慢慢把之前的程式碼精簡掉甚至移除。

重構的第三個原則:“簡潔邏輯而非減少程式碼”,重構最終的目標是需要符合軟體工程中單一指責以及開閉原則的,程式碼行數的多少不是關鍵,怎麼理清楚邏輯,讓後續維護方便,入手學習成本低才是最關鍵的。很多人以“從XXX行到XX行”為重構的目標,行數的減少是衡量指標之一,但絕不是最重要的指標。比如RxJava的引入,可能會增加程式碼量,但是邏輯更清晰了,增加功能更容易了,這就是成功的重構。

重構的另外一個原則就是:“合適的才是最好的”,很多人重構程式碼就是炫技,一旦給他重構程式碼的機會,就如脫韁野馬,引入大量自己並不熟悉的框架進行,覺得這是一個學習的好機會,一旦出現問題就無法解決。怎麼就算合適了,在我看來,合適的架構一定是以下幾個特徵:

  • 學習成本低,新人入手容易,市場上資料多;
  • 不過度設計,但是又容易擴充套件,以後換成新架構也方便;
  • 不要過度結偶;

前面兩點比較容易理解,第三點怎麼理解呢?寫程式碼久了,就會明白一個定律:“程式碼邏輯守恆定律”,就是無論你怎麼設計架構,程式碼邏輯是不會減少的,一個地方邏輯減少了,就一定會在另一個地方邏輯增加。解偶就意味著,你把不屬於這一塊業務的邏輯轉移到另外一個地方,過度解構要麼是劃分了很多個模組,要麼就是把對應的業務放在了“看不到”的地方,當“看不到”多了以後,就會造成查詢問題非常麻煩,比如過多的在Java使用註解或者編譯時註解。過度解偶其實就是隱藏了不必要隱藏的邏輯,對呼叫者完全透明,問題的追蹤就會在透明層被截斷,從而導致問題的產生。

怎麼實施重構

參與重構人數不宜過多,兩三人為宜;功能不宜分散,至少每個人應該要重構一個業務功能模組或者功能點,這樣可以更好減少溝通成本。

大規模重構,應該從下至上,先理清晰要達到的目標,先從底層邏輯開始重構,逐步到上層。比如在Android中對之前程式碼的重構,應該是先模組,後元件,然後逐漸到具體業務,這樣就可以保證整個過程中重構的一致性。

在進行重構之前,需要對要達到的重構目標做一個評估,是要完全重構完,還是隻需要對關鍵業務做梳理,亦或是需要整理出一個模版,然後分佈實施。不同的目標對應不同的做法以及不同的工作量;在重構之前還需要需要對當前關鍵業務做梳理,理清楚周邊支撐元件和必須要提前的工作量。

比如,某一次重構:

  • 目標:完成所有業務模組的MVP重構
  • 關鍵業務:叫車、訂單管理、地圖
  • 效果
    • 模組抽取(module1/moduel2...)
    • 基礎元件
      • 推送/IM
      • 網路
      • 支付
      • ...
    • 規範
  • 預估時間 30天/1人

圍繞關鍵業務設計,設計好了關鍵流程,重構就成功了一半。在重構中,還有一個比較基礎問題就是:編碼規範的問題;編碼規範儘量使用工具去最規範。類似於sonar/lint等工具做到自動識別,自動提醒,不要浪費太多時間在上面。

總結

快下班了,先寫到這裡吧,有什麼可以在評論中探討。

相關文章