重構改善既有代碼設計--重構手法02:Inline Method (內聯函數)& 03: Inline Temp(內聯臨時變量)
Inline Method (內聯函數)
一個函數調用的本體與名稱同樣清楚易懂。在函數調用點插入函數體,然後移除該函數。
int GetRating() { return MoreThanfiveLateDeliverise() ? 2 : 1; } bool MoreThanfiveLateDeliverise() { return _numberOfLateLiveries > 5; }
|
int GetRating() { return _numberOfLateLiveries > 5 ? 2 : 1; }
|
動機: 有時候你會遇到某些函數,其內部代碼和函數名稱同樣清晰易讀。也可能你重構了改函數,使得其內容和其名稱變得同樣清晰。果真如此,你應該去掉這個函數,直接使用其中的代碼。間接性可能帶來幫助,但非必要的間接性總是讓人不舒服。
另一種需要使用Inline Method (內聯函數)的情況是:你手上有一群不甚合理的函數。你可以將它們都內聯到一個大型函數中,再從中提煉出合理的小函數。實施Replace Method with Method Object (以函數對象取代函數)之前這麽做,往往可以獲得不錯的效果。你可以把所要的函數的所有調用對象的函數內容都內聯到函數對象中。比起既要移動一個函數,又要移動它所調用的其他所有函數,將整個大型函數作為整體來移動比較簡單。
如果別人使用了太多間接層,使得系統中所有函數都似乎只是對另一個函數的簡單委托,造成在這些委托動作之間暈頭轉向,那麽就使用 Inline Method (內聯函數)。當然,間接層有其價值,但不是所有間接層都有價值。試著使用內聯手法,可以找出那些有用的間接層,同時將那些無用的間接層去除。
做法:1、檢查函數,確定它不具多態性。如果子類繼承了這個函數,就不要將此函數內聯,因為子類午飯覆寫一個根本不存在的函數。
2、找出這個函數的所有被調用點。
3、將這個函數的所有被調用點都替換為函數本體。
4、編譯、測試。
5、刪除該函數定義。
Inline Temp(內聯臨時變量)
與Inline Method相同,有時候猶豫需要Extract Method,,需要對一些臨時變量進行內聯,而這個往往是Replace Temp with Query的一部分。簡單來說,當你看到這種
double basePrice = anOrder.basePrice(); return (basePrice > 1000);
對於這種情況,basePrice完全是多余的變量,完全可以用函數本身來替代他。這裏有個小竅門,你要內聯這個變量,你必須要保證函數之後沒有對這個變量進行過寫操作,換句話說,你可以利用C++的特性----const,將函數變量聲明為
const double basePrice = anOrder.basePrice();
然後你進行編譯,看看能不能編譯通過,如果能編譯通過,證明你這個變量確實只有讀操作沒有寫操作,那麽你就可以放心的進行內聯
return (anOrder.basePrice() > 1000);
這樣就完成了Inline Temp。
讀後感:
個人感覺,這個內聯無論是內聯函數還是臨時變量,其目的都在於簡化函數,但是並不是所有場景都適合,比如內聯函數,對於遞歸調用、多返回點、內聯至另一個對象中而該對象並無提供訪問函數…,當然還有其他的,比如公共用的時候,有時候提煉出來反而會更好,所以這種要視情況而定,但目標就是函數精簡化。
重構改善既有代碼設計--重構手法02:Inline Method (內聯函數)& 03: Inline Temp(內聯臨時變量)