聊一聊為什么不重構呢?
重構是提高質量的重要工具。許多開發方法都依賴于重構,尤其是對于敏捷方法,在更多計劃驅動的組織中也是如此。但事實上,是否以重構來處理設計中的某些問題呢?是否存在重構的障礙呢?
不重構的原因
存在質量問題而不進行重構的理由可以分為以下幾類:
資源
對所需資源的關注是不進行重構的一個經常被提到的原因。最常提到的資源是時間,比如“DDL不允許”,“有時候就是沒有時間”或者單純的“就是沒有時間”。
風險
同樣經常被提到的還有更改所涉及的風險,尤其是引入新的錯誤或其他問題,比如“這種重構很耗時間,而且引入錯誤的風險很大”,以及“反正還能用,管它干嘛”等等。
難度
另一個問題是進行更改的難度,比如“繼承很難正確重構”和“這種重構通常很困難”等等。
投資回報率
雖然重構可能會帶來好處,但也有成本,投資回報率也必須考慮,例如“必須再次權衡成本和好處,在承擔重構、重測試等方面的成本之前,必須明確收益。”
技術
項目的特點限制了重構的能力。例如,必須實現超出限制的第三方接口,擔心任何潛在的更改對系統其他部分的影響,對代碼的熟悉程度,處理遺留代碼,以及缺乏其他支持(如測試套件) ,尤其是“大量遺留代碼庫使重構變得困難”; “如果沒有測試方法,系統可能被破壞”; 以及“沒有時間進行重構的預算。”等等
管理
開發者并不總是能控制他們的時間使用。老板或客戶更有發言權,比如“想要重構,但老板不喜歡”、“只關注截止日期的老板”、“客戶不會為此付錢”等等。
工具
工具支持不足也被認為是不重構的一個原因,然而,這些的工具并不是那些進行重構的那些工具,某些重構非常痛苦,實際上是缺乏工具的支持。微軟對 Windows 進行了某種形式的重構,確定了執行重構的挑戰,例如管理組件間和分支間的依賴關系以及維護向下兼容,也許最令人驚訝的主題是完全不關心重構工具支持的存在和質量。
重構的障礙與時機
重構并非難在怎么做,而是難在何時開始做。對于一個高速發展的企業來說,停下來做重構從來就不是一個可接受的選項,“邊開飛機邊換引擎”才是公司想要的。當代碼還不是很混亂的時候,重構的必要性不高,相比不小心重構出錯導致熄火的風險來說,得過且過可能反而是一個明智之選。于是,各種技術債就這樣慢慢積累起來,直到業務因為各種技術債快跑不動的時候,才不得不用一些激進的重構手段快速的解決歷史頑疾。
代碼分析未必有效
在軟件工程中,往往使用每類加權方法(WMC)和繼承樹(Depth of Inheritance Tree,DIT) 來度量面向對象的設計,這些度量常常被表示為可能的設計問題,即WMC 或 DIT 的值越高,就越有可能出現問題。WMC 是類的大小度量的一種形式,最簡單的形式是類中方法數量的計數。DIT 捕獲繼承層次結構的一個特征,它是從類到層次結構根的最長路徑長度。然而,對軟件系統的測量表明,有些類具有很多方法,或者在層次結構中非常深。它就需要重構么?
實際上,工程師更傾向于限制類的深度,而不是方法的數量,但是當超過某個深度限制時,開發者傾向于不做任何事情。
兩個主要障礙
很多時候,無法確定 ROI 才是一個障礙,比如“如果不能對需要多長時間做出合理的估計,就不會管它。”也就是說,決定不重構并不是因為它被認為是一個壞主意,而是因為它的收益不確定。在特定情況下進行重構時,通常很少或根本不知道實際的 ROI 是什么。
一個潛在的障礙是很難將重構目標轉化為重構操作。需要的是一個決策支持系統,使從業人員能夠量化長期和短期效益。這將有助于為決定所需資源是否合理或是否容忍潛在風險提供信息,還允許開發人員和管理人員就是否重構做出明智的選擇。
重構的時機
具體地,Martin Folwer在《重構》一書中提到,需要識別壞味道,并提出了進行重構的4種情況,即關于重構的CRUD:
- 增:增加新功能的時候,發現需要重構來便于新功能的添加
- 刪:事不過三,消除重復
- 改:修復缺陷,改Bug的時候
- 查:代碼評審的時候得到了很多建設性的意見
也就是說,設計沒有表達出對需求的最新理解,或者需求沒有被很好地實現,而且已經發現更好的實現方法,以及發現了一個能使某個設計變得簡單、靈活的方法。實際上,重構的時機只是做出是否重構的判斷時機。
另外,使用重構工具的兩個好處是錯誤率更低,所需時間更少,因此好的工具支持應該在一定程度上解決開發人員的問題。只有當重構的決定已經做出時,重構工具的支持才會起作用。實際上,不使用自動化進行重構的原因可能包括信任、可預測性和復雜性。
小結
無論軟件設計質量問題是如何識別的,開發者都無法通過重構來根本消除這些問題。減少甚至消除重構的障礙有可能顯著提高軟件質量。一種方法是提供目標導向的重構支持,而不是操作導向的重構支持。另一個辦法是更好地量化效益,從而更好地告知是否重構的決定。