重構_改善既有代碼的設計

>>>  文章華國詩禮傳家—精彩書評選  >>> 簡體     傳統

重構,絕對是寫程序過程中最重要的事之一。在寫程序之前我們不可能事先了解所有的需求,設計肯定會有考慮不周的地方,而且隨著項目需求的修改,也有可能原來的設計已經被改得面目全非了。更何況,我們很少有機會從頭到尾完成一個項目,基本上都是接手別人的代碼,即使這個項目是從頭參與的,也有可能接手其他組員的代碼。我們都有過這樣的經驗,看到別人的代碼時感覺就像屎一樣,有一種強烈的想重寫的沖動,但一定要壓制住這種沖動,你完全重寫,可能比原來的好一點,但浪費時間不說,還有可能引入原來不存在的Bug,而且,你不一定比原來設計得好,也許原來的設計考慮到了一些你沒考慮到的情況。我們寫的代碼,終有一天也會被別人接手,很可能到時別人會有和我們現在一樣的沖動。所以,我們要做的是重構,從小范圍的重構開始。

重構不只可以改善既有的設計,還可以幫助我們理解原來很難理解的流程。比如一個復雜的條件表達式,我們可能需要很久才能看明白這個表達式的作用,還可能看了好久終于看明白了,過了沒多長時間又忘了,現在還要從頭看,如果我們把這個表達式運用Extract Method抽象出來,并起一個易于理解的名字,如果函數名字起得好,下次當我們再看到這段代碼時,不用看邏輯我們就知道這個函數是做什么的。如果對這個函數內所有難于理解的地方我們做了適當的重構,把每個細小的邏輯抽象成一個小函數并起一個容易理解的名字,當我們看代碼時就有可能像看注釋一樣,不用再像以前一樣通過看代碼的實現來猜測這段代碼到底是做什么的,好的代碼勝過注釋,畢竟注釋還是有可能更新不及時的。

《重構,改善既有代碼的設計》,這是一部經典之作,相信很多人都聽過或看過,看這本書時會發現,書中講的都是一些很簡單的東西,而且很多東西就是我們平時在做的,只是作者把它們總結了起來。比如說Rename Field,就是對不易理解其作用的字段起一個易于理解的名字,這個肯定我們都做過,但是更多時候,我們是對這種字段視而不見,比如曾經花了很久沒搞明白代碼的字段"IP"是什么的縮寫,最后發現竟然是“INPUT”。看過這本書的收獲是,讓重構融于整個寫代碼的過程中,讓重構不再作為一項獨立的任務,而是在寫代碼的過程中隨時隨地的進行,一個函數不容易理解,重構;添加新功能時很不方便,重構,使添加新功能變得理解。

這本書是用Java寫的,而且Java的版本很老。

書中的一些東西說得太絕對,比如說看到switch就重構,但這是不現實的,比如說Android開發,菜單的onOptionsItemSelected,這個肯定是重構不了的;對于很多控件的onClickListener,還是統一設置一個Listener并通過ViewID區分方便點,尤其是在Adapter的getView中,針對每個控件new一個onClickListener會生成太多對象。當然,不是說這個重構手法無效,而是這個手法提醒我們,當看到這樣的情況時需要認真考慮一下,當前的情況是否需要重構,如果確定不需要,就那樣好了。

但是有些東西還是很值得注意的,比如封裝集合(Encapsulate Collection),當調用者請求一個類的一個集合對象時,我們最好不要返回這個集合對象,而是返回這個集合對像的一個不可修改的副本,并增加添加/移除數據的函數。比如Android開發的Adapter,我們經常會為了方便給Adapter添加返回數據集合與設置數據集合的方法,但這是不安全的,我們不能確定調用者獲得這個集合后會做什么事情,如果調用者修改了這個集合的內容我們也對其一無所知,在Android中,如果調用者在非UI線程獲得了Adapter列表的數據并修改是會出問題的。

重構前,先檢查自己是否有一套可靠的測試機制。這些測試必須有自我檢驗的能力,畢竟重構可能破壞掉一些東西,我們要靠測試幫助我們發現這些問題,不要因為測試無法捕捉所有bug就不寫測試, 因為測試的確可以捕捉到大多數bug。不過,說來慚愧,我很少寫測試,尤其是Android項目。

書中全是一些很簡單的手法,我相信,我們肯定都用過其中的大部分重構手法,只是沒有察覺。這本書只是對其進行了一個總結,并讓我們意識到重構這項技能,并讓重構融入我們整個寫程序的過程中,讓重構無處不在。

書中的一些重構手法,在我感覺可能就不算是重構手法,比如給函數添加參數,如果參數不夠又必須添加,我們肯定會添加的,這算是功能修改還是重構,隨便怎么理解吧,不過作為筆記,還是把所有這些都記錄下來了。


2022-12-08 19:12:44

[新一篇] 重刊洛陽伽藍記 山濤論

[舊一篇] 金戈鐵戟:中國古兵器的歷史與傳統 鐘少異
回頂部
寫評論


評論集


暫無評論。

稱謂:

内容:

驗證:


返回列表