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