介紹
我以前寫過《php雜談 《重構-改善既有代碼的設計》之一重新組織你的函數》,其中代碼壞味道,還有深入挖掘的地方,所以我再重點把這一篇提出來,分幾篇再提一下,不要閑我煩。
我覺得重構是我們要用一生去研究的地方,跟文學一樣,我們要用一生追求優秀的文學作品。
我盡量以漫畫的形式表現。
味道
Duplicate Code
狀況:如果你在一個以上的地點看到相同的程序結構,那么
當可肯定:設法將它們合而為一,程序會變得更好。
1、同一個class內的兩個函數含有相同的表達式。——需要Extract Method,提煉出重復代碼,然后讓兩個地點都調用被提煉出來的那一段代碼。
2、兩個互為兄弟的subclass內含相同的表達式,要避免這種情況——需要兩個class都使用Extract Method,把Extract的Method推入superclass內。
3、兩個毫不相干的classes內出現Duplicate Code,你應該考慮對其中一個使用Extract Class,將重復代碼提煉到一個獨立class中,然后在另一個class內使用這個新class。
Long Method
不熟悉面向對象技術的人,常常覺得對象程序中只有無窮無盡的delegation(委托),根本沒有進行任何計算。和此類程序共同生活數十年之后,你才會知道,這些小函數有多大價值。——間接層所能帶來的全部利益:解釋能力,共享能力,選擇能力。——都是由小型函數支持的。
很久以前程序員就已認識到:程序愈長愈難理解。不過短函數讓代碼閱讀者必須經常轉換上下文去看看子程序做了什么,然短函數容易理解的真正關鍵在於一個好名字。如果你能給函數起個好名字,讀者就可以通過名字了解函數的作用,根本不必去看其中寫了些什么。
可遵循的一條原則:每當感覺需要以注釋來說明點什么的時候,我們就把需要說明的東西寫進一個獨立函數中,並以其用途命名。——關鍵在函數“做什么”和“如何做“之間的語義距離。
函數內如果有大量的參數和臨時變量,會對你的函數提煉形成阻礙,導致可讀性幾乎沒有任何提升。——可以使用Replace Temp with Query來消除暫時元素。Introduce Parameter Object則可以將過長的參數列變的更簡潔些。
如果仍然有太多臨時變量和參數,那就應該“用對象替換方法”。
如何確定該提煉哪一段代碼?尋找注釋。尋找條件式和循環。
總結
由於這一篇內容太多,所以分批來寫,大家勿見怪。——如果有理解上的錯誤,請指教!
推薦
希望各位高手能把平時寫代碼的經驗,好的代碼形式,給大家分享一下。