遺留系統重構的模式與原則

設計模式強調爲開發大規模系統提供可複用的設計指南。 —— 《反模式:危機中軟件、架構和項目的重構》

就重構的基本原則來說,倒也不是很複雜:

  • 小步前進。走一小步,提交一次代碼,方便回滾,有一天你會懂的。
  • 隨時可用。如果不能保證隨時可用,那就說不上是重構了。
  • 融入日常。

當你習慣了重構,記得在日常工作中使用。

重構模式:EPDCA

我嘗試從書中找到一個合適的模式,但是都沒有發現符合我的步驟。便在 PDCA 的前面加了個 E,代表了 evaluate:

  1. 識別需要重構的地方
  2. 制定重構計劃,
  3. 執行計劃的重構任務
  4. 使用測試對重構是否影響業務功能進行檢察
  5. 調整下一次重構策略

對系統進行大規模重構的過程中,最難的地方在於識別,因爲代碼壞味道多的地方不一定是價值最高的。尋找你的價值曲線,尋找價值高、實施難度低的部分,是最體現你價值的地方。

四級重構

實踐的過程中,我們以拆解的方式,一步步由系統架構到代碼級拆分。在某次喫飯的過程中,我發現不太對勁。我明明用的是敏捷式的重構方式,而非瀑布模式。它對應於四個不同的重構級別:

  • 架構重構。在不改變業務邏輯的情況下,根據單一職責和依賴倒置原則的思想:對系統進行模塊拆分與合併,以明確職責降低耦合度;對包進行重新規劃,劃分包之間的邊界,減少代碼間的耦合。
  • 模型重構。在包含測試的情況下,通過識別和發現模型的行爲,將行爲聚合到模型中:根據方法名稱、參數、返回判定內聚到模型中;從流程梳理是否符合業務場景 。
  • 模式重構。對於特定代碼壞味道產生的問題,通過結合架構模式、設計模式來提升可讀性。如:使用工廠模式統一管理對象的創建;使用策略模式降低複雜度。
  • 代碼重構。對於一些小的代碼壞味道,可以通過 IDE 重構來快速改善即有代碼,而不會影響到業務功能。如:複雜條件語句的提取;使用參數對象重構參數過多。

對應的模式如下圖所示:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xzU7BDon-1578581150861)(https://migration.ink/images/refactoring-levels.png)]

這一點倒是與我們設計系統的時候,採用的《架構金字塔》頗爲一致的:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4HUMc1Lt-1578581150862)(https://migration.ink/images/architecture-primard.jpg)]

小步前進

小步前進,拉一下最新的代碼。

不論改動的大小,一旦變動的文件多了,如移包、重命名用得廣泛的類等等,記得隨時提交。

多說無益,步子邁大的時候,你就會回到這句話上。

Git 工作流

如果你們使用的版本控制工具,還不是 Git 話,那麼你們可能需要好好反思一下,爲什麼會到現在的這種地步?

Master 機制

或許因爲我合作的同事主要是 ThoughtWorks 的員工,所以在項目合作上,代碼水平並不會太差;或許因爲我能容忍那些年輕的開發人員犯的錯。

我是一個喜歡用 master 分支的開發人員,主要是作爲一個 Tech Lead,我並不想成爲一個專職的 code reviewew。

所以,在 master 分支上重構,對於每個人都是一個極大的考驗。有沒有足夠的測試覆蓋?有沒有足夠的工程支持?有沒有配合的團隊合作?

PR 機制

對於採用 pull request / merge request 機制的團隊來說,重構並不會一帆風順。

對於大的重構來說,如目錄調整,你還能在花點時間重做。如果是代碼重構,一旦重來的話,你可能會忘記你到底修改了什麼。

也經常不得不找個夜深人靜的時間,加會班,提交上代碼。

所以,當你採用 PR 機制的時候,記得做一下筆記,寫寫你打算怎麼改。

建立遠景與方向

TBD

拉通:對齊目標

會遇到不一樣的需求,有的是明確的重構需求,有的則是隱藏在需求之後,有的則是看上去沒有而已。

明確潛在風險

你懂的。

人評估

並非很有的人都具備足夠的能力參與到重構的過程中。

所以,在我們進入重構之前,需要:

  • 確保對方有足夠的能力
  • 確保和對方對於重構有共同的看法
  • 確保對方能配合你工作

爲此,需要一些培訓,又或者是激烈的討論。

他/她們需要具備以下的基本技能:

  • 理解面向對象設計
  • 瞭解設計模式
  • 瞭解寫測試的重要性
  • 瞭解爲什麼要重構
  • 追求代碼質量

當然了,在瞭解的基本上有更深入的理解也是不錯的。

重構範圍

對於一個大的系統來說,系統的每一部分並非都是等價的。

系統的核心就是系統的 core domain(核心域),一個有能力的管理者,能識別到哪一部分是系統的核心組成,併爲它分配最好的開發人員;與此同時,對於支撐的部分來說,管理者只會分配少數的核心開發人員,只用於確保功能能按期完成。

按照 DDD 的思想來看,就是核心域、支撐域、通用域的區別。

產出物

KPI 度量

重建規範

團隊賦能

原則與模式

詳細內容見:https://migration.ink/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章