2009年2月25日 星期三

極品程式碼--refactoring踢到鐵板(Part 3 後記)

第一篇第二篇中,分享了一次Refactoring的經驗。當時覺得最大的考驗是意志力與信念。所以描述(抱怨)問題的困難度,以及心路歷程佔的篇幅最多。現在回頭想來,其實這篇兩篇文章真正分享的實務技巧,似乎可以化約成簡單幾句話:

當程式碼很冗長,變數糾結得很複雜時,可以用extract method來將程式分割成小塊。由於變數的scope過大以及使用不當,extract出來的method將會出現ref以及out的參數。留待後續的refactor動作逐步消除或簡化這些參數。這個方法似乎只適用於C#(或是其他支援ref參數的程式語言)。

有另一點可以分享的經驗,當時也漏寫了。文字比對工具(如Merger, WinMerge)通常用於版本的比對,但是對於Refactoring也是很有幫助的。假想前人用copy-paste複製幾百行的程式碼,然後只改兩三個小地方。他當時做這件事只要15秒,但是你現在要看這一大段程式,可能需要用眼力比對十分鐘,頭暈目眩加上幾次嘔吐才能確認改了哪裡。文字比對工具在這裡就派上用場了:兩大塊很像的程式碼,一用工具比對就無所遁形。處理copy paste程式常用的步驟概述如下:
1. 將兩段很像的程式A與B剪貼到文字比對工具進行比對。找出差異處並記錄下來。
2. 將A整段程式做extract method,變成myMethod(arg list)
3. 將myMethod一般化,讓A與B都能由這個method達成。有時差異只是一些數值,只要將差異點提取出來,變成參數即可。但有時是程式邏輯的差異,必須改些程式嗎。
4. 用myMethod(..)取代B
5. 如果copy-paste版本有很多,不是只有A, B兩版,就重複進行類似作法,只是第三步一般化可能會變得複雜一些。有時需要將myMethod(..)變成Template Method(關於Template Method詳閱Design Patterns一書)。

最後一點離題的補充,關於匈牙利命名法的問題。我發現約爾談軟體有一篇文章在說明匈牙利命名法的原意,以及如何被微軟誤用。蠻有趣的一篇文章。

沒有留言: