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

語言: CN / TW / HK

theme: cyanosis

什麼是重構

什麼是重構

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

重構對性能的影響

重構不是代碼優化,重構注重的是提高代碼的可理解性與可擴展性,對性能的影響可好可壞。

評估是否需要重構

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

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

重構的第一步

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

重構的過程

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

營地法則

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

重構的原則

理解重構

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

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

兩頂帽子

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

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

為何重構

重構改進軟件的設計

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

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

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

重構使軟件更容易理解

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

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

重構幫忙找到bug

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

重構提高編程速度

不同質量的設計,隨着功能累計,添加新功能所需的時間。

重構提高編程速度

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

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

何時重構

見機行事的重構

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

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

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

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

撿垃圾式重構

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

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

優秀的程序員知道,添加新功能最快的方法往往是先修改現有的代碼,使新功能容易被加入。

有計劃的重構

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

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

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

Branch By Abstraction

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

Code Review時重構

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

何時不應該重構

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

重構的挑戰

延緩新功能開發?

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

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

代碼所有權

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

版本控制問題

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

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

測試

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

重構、架構和YAGNI

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

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

重構與軟件開發過程

敏捷開發的三大實踐

  • 自測試代碼
  • 持續集成
  • 重構

重構與性能

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

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

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