重構:改善既有程式碼的設計 讀書筆記- 重構的原則

語言: CN / TW / HK

theme: cyanosis

什麼是重構

什麼是重構

在不改變程式碼外在行為的前提下,對程式碼做出修改,以改程序序的內部結構。

重構對效能的影響

重構不是程式碼優化,重構注重的是提高程式碼的可理解性與可擴充套件性,對效能的影響可好可壞。

評估是否需要重構

如果需要給程式新增特性,但因為程式碼缺乏良好結構而難以更改,那可以先重構使其易於修改。

需求的變化使重構必要,如果程式碼正常執行,不會再被修改,那完全可以不去重構。

重構的第一步

確保即將修改的程式碼擁有一組可靠的測試

重構的過程

分小步走,每修改一小步,重新編譯、測試、提交。

營地法則

保證你離開時的程式碼庫一定比來時更健康。

重構的原則

理解重構

重構(名詞):對軟體內部結構的一種調整,目的是在不改變軟體可觀察行為的前提下,提高其可理解性,降低其修改成本

重構的關鍵在於運用大量微小且保持軟體行為的步驟,一步步達成大規模的修改。

兩頂帽子

程式碼開發過程中兩種截然不同的行為,新增新功能重構

不應該經常變換帽子,每次只應該專注於其中一項工作。

為何重構

重構改進軟體的設計

如果沒有重構,程式的內部設計(或者叫架構)會逐漸腐敗變質。

當人們只為短期目的而修改程式碼時,他們經常沒有完全理解架構的整體設計,於是程式碼逐漸失去了自己的結構。

程式碼結質量的變質具有累計效應、破窗效應

重構使軟體更容易理解

合理的重構能讓程式碼“自解釋”

比讓計算機讀懂程式碼更難的是,讓“人”讀懂程式碼。

重構幫忙找到bug

深入理解程式碼的所作所為,並立即把新的理解反映在程式碼當中,在這個過程中,bug自然會被發現。

重構提高程式設計速度

不同質量的設計,隨著功能累計,新增新功能所需的時間。

重構提高程式設計速度

需要新增新功能時,內部質量良好的軟體讓我可以很容易找到在哪裡修改、如何修改。良好的模組劃分使我只需要 理解程式碼庫的一小部分,就可以做出修改。如果程式碼很清晰,我引入bug的可能 性就會變小,即使引入了bug,除錯也會容易得多。理想情況下,我的程式碼庫會逐步演化成一個平臺,在其上可以很容易地構造與其領域相關的新功能。

“設計耐久性假說”:通過投入精力改善內部設計,我們增加了軟體的耐久性,從而可以更長時間地保持開發的快速。

何時重構

見機行事的重構

預備性重構:讓新增新功能更容易

重構的最佳時機就在新增新功能之前。

幫助理解的重構:使程式碼更易懂

當代碼難以理解,使用重構來幫助理解。

撿垃圾式重構

在日常開發過程中,對不好的實現,通過重構進行清理。

專案計劃上沒有專門留給重構的時間,絕大多數重構都在做其他事(新增新功能或者修復bug)的過程中自然發生。

優秀的程式設計師知道,新增新功能最快的方法往往是先修改現有的程式碼,使新功能容易被加入。

有計劃的重構

問題在某個區域逐漸累積長大,最終需要專門花些時間來解決。

分離重構和新增新功能的提交是比較有益的工作方式。

大規模的重構只在必要的時候進行,更推薦的方法還是隨時隨地重構工作相關的程式碼。

Branch By Abstraction

如果要替換掉一個正在使用的庫,先引入抽象層,相容新舊兩個庫的介面

Code Review時重構

和原作者一起結對程式設計,通過CR過程中提出的重構建議,提高程式碼的質量。

何時不應該重構

  • 程式碼不需要被理解和修改時。
  • 重寫比重構容易時。

重構的挑戰

延緩新功能開發?

重構的唯一目的就是讓我們開發更快,用更少的工作量創造更大的價值。

有時候需要取捨,新增的功能很小但是需要做很大規模的重構時,可以先新增新功能。

程式碼所有權

推薦團隊程式碼所有制,而不是細粒度的強程式碼所有制。

版本控制問題

如何解決在隔離的分支,整合回主線,需要解決大量衝突的問題。

採用持續整合(CI),基於主幹開發的方法,每天至少向主線整合一次,確保主線隨時處於健康狀態。

測試

“不會改變程式可觀察的行為”,要求程式碼應該有一套完備的測試套件,並且執行速度要快,能在一步小的重構後,馬上驗證程式的正確性

重構、架構和YAGNI

一開始就完成完美的架構設計是不可能的,當擁有重構的時候,我們可以做簡單設計(也稱增量式設計或者YAGNI)

只根據當前的需求來構造軟體,同時把軟體的設計質量做得很高。隨著對使用者需求的理解加深,我會對架構進行重構,使其能夠應對新的需要。

重構與軟體開發過程

敏捷開發的三大實踐

  • 自測試程式碼
  • 持續整合
  • 重構

重構與效能

短期看來,重構的確可能使軟體變慢,但它使優化階段的軟體效能調優更容易,最終還是會得到好的效果。

效能優化的過程:度量->發現效能熱點->去除熱點

大多數程式的效能都消耗在一小部分的程式碼上,要先對程式有清楚的理解,不要通過臆想進行效能優化