重構並非難在怎麼做,而是難在何時開始做。
對於乙個高速發展的公司來說,停下來做重構從來就不是乙個可接受的選項,「邊開飛機邊換引擎」才是這種公司想要的。當**還不是很混亂的時候,重構的必要性不高,相比不小心重構出錯讓引擎熄火的風險來說,得過且過可能反而是乙個明智之選。於是各種技術債就這樣慢慢積累起來,直到業務因為各種技術債快跑不動的時候,架構師們才不得不用一些激進的重構手段快速的解決歷史頑疾。如果重構獲得了成功,大多數架構師在回顧過程的時候都會感慨:「要是早點重構就不會這麼麻煩了」,不過在下一次重構到來之前,永遠沒人知道「早點」究竟是何時,同樣的感慨會反覆被提起。
就沒有什麼辦法找到最合適的重構時機麼?可能真沒有。不過通過評估重構收益可以早一點察覺到重構的必要性,從而至少能做到稍微「早點」。
重構的根本目的就是讓業務能跑的更快,達到更高的開發效率。對於一般工程專案而言,基本不會出現無法實現的需求,只要有充足的時間,需求總能被實現。在這裡提到的「需求」包含業務中所有明確或潛在需要的東西,並不侷限於產品需求,各種效能、可用性、柔性指標也都是需求的一種。很顯然,在需求一定的情況下,開發效率越高所需要花費的時間或人力就會越少,業務就能跑的更快。
並不是任何的重構都能達到預期的效果,因為重構本身需要付出成本,重構之後的架構也不一定真的能提公升開發效率,只有通過估算發現「重構淨收益」為正才是重構的好時機。
「重構淨收益」由以下公式定義:
重構淨收益 = 舊架構開發效率 - 新架構開發效率 - 重構成本 - 遷移成本
公式中每個專案的解釋:
舊架構開發效率:採用舊架構完成需求所需要的時間;
新架構開發效率:採用新架構完成需求所需要的時間;
重構成本:重構所需要的時間,這一般是一次性投入;
遷移成本:為了解決新架構帶來的額外問題所花費的時間,包括新架構的bug修復、業務測試回歸成本、學習成本等。
重構淨收益是乙個長期收益,隨著需求不斷演進新舊架構開發效率帶來的差異會日漸明顯,直到能夠超過重構成本和遷移成本,如果估算發現收益為正,那麼意味著當前就是重構的好時機,應該著手準備了。
舉個使用公式的例子。
假設有乙個服務由於長期開發不注重**復用,重複**頗多,開發乙個新功能,比如增加一種新的通用引數,就不得不修改幾乎所有介面的**,那麼是否值得消除重複**?按直覺來說,答案應該就是肯定的,但實際上並非如此,這些情況基本可以用「重構淨收益」公式來解釋。
如果這個服務基本不再維護,舊架構並不會持續的帶來開發成本,假如重構成本大於使用舊架構完成需求的時間,那麼重構收益就一定為負,重構不值得做;
如果重構會帶來很大的遷移成本,比如會造成幾十萬行無人維護缺乏測試覆蓋的舊**發生改動,無人能夠保證改動正確性,那麼就算重構本身成本不高(假設能夠利用一些指令碼大批量抽取重複的**),這種重構也是值得商榷的;
如果重構之後的新架構過於超前,學習門檻很高,當前團隊很難可靠的掌握高效的開發方法,最終這些學習成本會被放在遷移成本之中,假如過大也意味著收益為負,重構不值得做或者必須換一種更讓團隊容易接受的方案。
限於篇幅,這裡就不展開說明公式的更多用法,大家不妨拿自己工作中的例子套用試試,看是否有幫助。需要特別注意,就算重構淨收益為正,也並不意味著應該停下業務做重構,重構帶來的是長期收益而業務需求代表著短期收益,架構師有責任在確保業務正常運轉的情況下為未來做準備。
原文:
重構時機和重構方法之間的對應關係
id 需要重構的訊號 對應的重構方法 1出現了重複 提取或者重組類 提取或者重組函式 方法 用多型處理子類重複 2兩個類耦合太多,太親密 提取或者重組類,提取或者重組函式方法 3出現了 行尺寸極其龐大的類 提取或者重組類 4沒有實際作用的懶惰類 提取或者重組類 5體積龐大的方法函式 提取或者重組函式...
Spring bean的建立時機
建立物件的時機 1 在預設的情況下,在spring容器啟動的時候建立物件 在spring配置檔案中,只要根據以上的三種方式的其中一種配置了,spring容器就會建立物件 好處 spring容器和web容器整合的時候,當web容器啟動的時候就可以初始化spring容器了,如果這個時候 spring容器...
觸發Full GC的時機
由於full gc的耗時是minor gc的十倍左右,所以full gc的頻率設計得比minor gc低得多。現總結一下觸發full gc的情況。在那些實現了cms的比較新的虛擬機器中,如果配置了 xx useconcmarkswapgc,則啟用cms 演算法,cms會周期性地檢查老年代的情況,每隔...