發(fā)布于:2021-01-27 10:49:14
0
310
0
在重構(gòu)一些代碼之前進(jìn)行單元測試通常是個(gè)好主意。不過,我今天要違背這一點(diǎn),告訴你們,這并不是必須的。
很多時(shí)候,應(yīng)該重構(gòu)的代碼并沒有被重構(gòu),這是因?yàn)樵谥貥?gòu)之前必須始終有單元測試。
在許多情況下,相同的代碼在許多修改中都沒有得到改進(jìn),因?yàn)閯?chuàng)建重構(gòu)所需的單元測試的工作量太大了。
我認(rèn)為這是一個(gè)遺憾,因?yàn)樵谥貥?gòu)之前并不總是有必要進(jìn)行單元測試。
放棄安全網(wǎng)
如果你去看馬戲,你會注意到有些表演總是有一個(gè)安全網(wǎng)在下面,因?yàn)樘丶际侨绱宋kU(xiǎn),總是有失敗的機(jī)會。
你也會注意到,有些表演沒有安全網(wǎng),因?yàn)楸M管有危險(xiǎn),但由于表演人員的訓(xùn)練,危險(xiǎn)是非常小的。
今天我將討論一些實(shí)例,在這些實(shí)例中,在進(jìn)行重構(gòu)之前,不一定需要有一個(gè)安全網(wǎng)。
自動重構(gòu)
這是一件容易的事,應(yīng)該很明顯。如果您使用Visual Studio,Eclipse或IntelliJ之類的現(xiàn)代IDE,那么您無疑會看到我所說的“右鍵單擊重構(gòu)”選項(xiàng)。
任何一種自動重構(gòu)在任何時(shí)候都是非常安全的,不必?fù)?dān)心功能會發(fā)生變化,這些自動重構(gòu)只是對代碼應(yīng)用一種算法來產(chǎn)生所需的結(jié)果,而且在幾乎所有情況下都不會改變功能。
您可以信任這些重構(gòu)工具,因?yàn)椴豢赡艹霈F(xiàn)人為錯誤。
任何時(shí)候你可以選擇使用自動重構(gòu),就去做吧!即使你有單元測試,這也是有意義的。當(dāng)我和某人配對,他們手動重構(gòu)“提取方法”或“重命名”之類的東西時(shí),我總是感到驚訝。
大多數(shù)時(shí)候,您想對某些代碼執(zhí)行的所有操作都可以在自動重構(gòu)菜單中找到。
小步重構(gòu)
雖然不像自動重構(gòu)那樣安全,但如果你的重構(gòu)只是一小步,那么你的大腦理解它并防止任何副作用的可能性就大得多。
這方面的一個(gè)很好的例子就是我關(guān)于重構(gòu)去除條件的文章。
一般的想法是,如果你可以做一些非常簡單的小步驟,這些步驟非?,嵥?,幾乎不可能出錯,那么你最終可以做一個(gè)大的重構(gòu),作為這些小修改的凈效果。
這是一個(gè)判斷的召喚,由你來決定你所做的是否只是一小步。
我確實(shí)發(fā)現(xiàn),如果我想做一個(gè)不是小步重構(gòu)的重構(gòu),我通常可以把它分解成一系列我非常自信的小步(大多數(shù)時(shí)候這些都是自動重構(gòu))。
將方法轉(zhuǎn)換為類
我討厭上課。很多時(shí)候,每個(gè)人都不敢從一個(gè)龐大的課程中學(xué)習(xí)東西,因?yàn)樗芸赡軙屏?,并且為該課程編寫單元測試將花費(fèi)數(shù)年時(shí)間。
一個(gè)簡單的步驟,極大地改進(jìn)了體系結(jié)構(gòu),并允許您最終創(chuàng)建單元測試,就是獲取該類的一大塊,將其移動到一個(gè)新的類中,并將所有的邏輯保持在原來的狀態(tài)。
它并不總是完全干凈的,您可能需要將一些依賴項(xiàng)傳遞給新方法或新類構(gòu)造函數(shù),但是如果您可以這樣做,它可以是一個(gè)簡單而安全的重構(gòu),允許您為新類編寫單元測試。
顯然,這個(gè)危險(xiǎn)比我之前提到的其他兩個(gè)危險(xiǎn)要稍微大一些,但是它也具有巨大的“優(yōu)勢”。
單元測試或測試代碼本身
另一個(gè)顯而易見的問題是,除非你要編寫元單元測試,否則你將不得不在這個(gè)問題上過得有點(diǎn)危險(xiǎn),你真的沒有選擇。
我想每個(gè)人都會同意重構(gòu)單元測試很重要,那么,為什么沒有人害怕重構(gòu)單元測試呢?
我只舉這個(gè)例子來說明你不應(yīng)該害怕在沒有單元測試的情況下重構(gòu)代碼。
我不是提倡魯莽行事
我知道你們有些人現(xiàn)在很緊張,請放心,我的信息不是在沒有單元測試的情況下隨意重構(gòu)代碼,我的信息只是在考慮重構(gòu)時(shí)使用節(jié)制
不要因?yàn)樽裱粭l需要先進(jìn)行單元測試的硬性規(guī)定而放棄重構(gòu)。
相反,我建議一些重構(gòu)是如此的瑣碎和安全,以至于如果在選擇離開代碼是因?yàn)閱卧獪y試將花費(fèi)太長的時(shí)間,還是在沒有安全網(wǎng)的情況下重構(gòu)代碼之間,不要成為一個(gè)懦夫。動動腦筋!
會讓你難受的事情
即使使用自動重構(gòu),也有一些事情需要注意,即使是那些也可能會失敗并給您帶來各種各樣的問題。
這些問題中的大多數(shù)不會存在于你的代碼庫中,除非你正在做一些瘋狂的事情。
如果你在C#中使用動態(tài),或者某種PInvoke、不安全(指針操作)或COM互操作,所有的賭注都在重命名之類的東西上。
反射。小心這個(gè)。這真的會讓你大吃一驚。如果你使用反射,更改方法名稱或類型可能會導(dǎo)致僅在運(yùn)行時(shí)才會出現(xiàn)的故障。
代碼生成。也要注意此問題。如果生成的代碼取決于系統(tǒng)中某些功能的特定實(shí)現(xiàn),重構(gòu)工具不會有任何想法。
外部發(fā)布的接口。這一點(diǎn)毋庸置疑,但我將在這里提到這一點(diǎn)非常重要。小心其他人使用您發(fā)布的API。無論您是否有單元測試,重構(gòu)發(fā)布的API都會給您帶來一大堆噩夢。
這個(gè)列表并不是為了嚇唬你不要重構(gòu),但是如果你知道這個(gè)列表中的任何東西都在你的代碼庫中,在你重構(gòu)之前檢查一下。確保你正在重構(gòu)的代碼不會受到這些東西的影響。
作者介紹