重構2-重新組織函數
重構的基本技巧--小步前進,頻繁測試。
模式是你希望到達的目标,重構則是到達之路。
在單程序軟體中,你永遠不必操心多麼頻繁地調用某個函數,因為函數的調用成本很低。但在分布式軟體中,函數的往返必須被減至最低限度。
(Extract Method)提煉函數
含義:将一個複雜的大函數,提取整合為多個簡單的小函數,通過函數名很明顯的顯示出此小函數要表達或者要展示的作用。
特别注意事項:
- 小函數的命名,要讓别人立馬可以看到函數要表達的含義。
- 對于大函數中的局部變量要特别小心,看是如何被調用和使用的。
- 對于需要傳回參數的函數,盡可能使用多個小函數來處理傳回值,盡量不要使用一個函數傳回多個參數。
(Inline Method)内聯函數
含義:函數的内部要表達的代碼和函數名稱一樣簡單時,就不需要單獨使用函數,而直接使用本體就可。
int _nNumberOfLateDeliveries=10;
private int GetRating()
{
return (moreThanFiveLateDeliveries()) ? 2 : 1;
}
private bool moreThanFiveLateDeliveries()
{
return _nNumberOfLateDeliveries > 5;
}
對于上面的代碼,在函數moreThanFiveLateDeliveries()中的函數主體特别簡單,很容易看懂,那麼此時就不需要使用此函數,直接在調用者GetRating()中,直接使用函數主體,以減少内聯函數的使用。
特别注意事項
- 并不是所有的内聯函數都沒有價值,你需要找到有意義的内聯函數,将無意義無用的内聯函數優化掉。
(Replace Temp with Query)以查詢取代臨時變量
含義:如果函數中有臨時變量儲存着某一表達式的運算結果,則需要将此表達式提煉到一個獨立函數中,将這個臨時變量所有的引用點都替換為這個獨立函數。
- 臨時變量隻是暫時的,而且隻能在函數内部使用,如果将其所代表的表達式優化為一個單獨的函數則可以多方進行調用。
- 確定提煉出來的函數無任何副作用。(該函數并不修改任何對象内容)
(Replace Method with Method Object)以函數對象取代函數
含義:對于大型函數,往往代碼比較臃腫,那麼就需要将大函數進行拆分,放再對象中成為對象中的字段,然後就可以在同一個對象中将這個大型函數分解為多個小型函數。
(Substitute Algorithm)替換算法
含義:如果想 将某一個算法替換為另一個更清晰的算法,将函數本體替換為另一個算法即可。
(Remove Assignments To Parameters)移除對參數的指派
含義:代碼對一個參數進行指派,以一個臨時變量取代該參數的位置。其實就是對于參數而已,如果可以在函數主體中之間使用,則就不需要在先将其指派給參數,後使用參數。而且對于參數,最好隻指派一次,讓其表示的函數單一。
(Split Temporary Variable)分解臨時變量
含義:臨時變量隻能代表單一的表達式,如果它既不是循環變量,又不被用于收集計算結果。那麼針對每次指派,創造一個獨立,對應的臨時變量。
每個變量隻承擔一個責任,同一個臨時變量承擔倆件不同的事情,會另代碼閱讀者混亂糊塗。
(Introduce Explaining Variable)引入解釋性變量
含義:對于函數中的複雜表達式,需要進行優化,将其重構成函數,指派給一個臨時變量,用臨時變量來代替這個複雜表達式來向程式解釋具體的用途。
對于臨時變量,應該建立一個具體特殊含義,可以表達此複雜表達式的變量來用以說明。