refactoring Patterns:第二部分

refactoring Patterns:第二部分

爲什麼要 Refactoring

 

爲什麼要去改變已經可以正確運行的軟件?這樣的改變是否影響到我們的設計,從而進一步改變我們對於面向對象系統進行設計的方法和思路?本部分試圖回答這些問題。
Refactoring雖然需要更多的"額外工作",但是它給我們帶來的各種好處顯然值得我們做出這樣的努力:

簡化測試
一個好的Refactoring實現能夠減少對新設計的測試量.因爲Refactoring的每一步都保持可觀察的行爲,也就是保持系統的所有單元測試都能順利通過。所以只有發生改變的代碼需要測試.這種增量測試使得所有的後續測試都建立在堅實的基礎之上,整個系統測試的複雜性大大降低。

更簡單的設計
Refactoring降低初始設計的複雜程度.Gamma指出複雜設計模式的一個陷阱是過度狂熱:"模式有其成本(間接性、複雜化),因此設計應該達到需求所要求的靈活性,而不是越靈活越好"。如果設計試圖介入太多以後可能需要的靈活性,就會產生不必要的複雜和錯誤。Refactoring能夠以多種方式擴展設計。他鼓勵爲手頭的任務建立剛剛合適的解決方案,當新的需求來到時,可以通過Refactoring擴展設計。

Refactoring增進軟件可理解性
程序的最終目的是爲了指引計算機完成人們需要完成的事情。但是,要完成這個目標並非想象的那麼容易。

程序編寫是人的活動,人首先要理解才能行動。所以,源代碼的另一個作用就是用於交流的工具。其他人可能會在幾個月之後修改你的代碼,如果連理解你的代碼都做不到,他又如何完成所需的修改呢?我們通常會忘掉源代碼的這種用處,儘管它可能是源代碼更重要的用處。不然,我們爲什麼發展高級語言、面嚮對象語言,爲什麼我們不直接使用彙編語言甚至是機器語言來編寫程序?難道我們真的在意計算機多花了幾個CPU週期去完成一件事?

如果一個人能夠理解我們的代碼,他可能只需要一天的時間完成一個增加功能的任務,而如果他不理解我們的代碼,可能需要花上一個禮拜或更長的時間。這裏的問題是,我們在編寫代碼的時候不但需要考慮計算機CPU的想法,更要把以後的開發者放在心上。除非,你寫代碼的唯一目的就是把它丟掉。你不想讓任何別的開發人員用到這段代碼,包括你自己。因爲你不可能記得所有你寫過的代碼,如果你經常回過頭去看一下自己的代碼,你就會體會到代碼的可理解是如何重要。

Refactoring可以使得你的代碼更理解,Refactoring支持更小的類、更短的方法、更少的局部變量、更小的系統耦合,Refactoring要求你更加小心自己的命名機制,讓名字反映出你的意圖。如果哪一塊代碼太複雜以至於哪一理解,你都需要對他進行Refactor。

你可能認爲,反映代碼的意圖應當是註釋和文檔的責任。假設你寫好了一段程序,給他加上註釋,來說明你這段代碼完成了什麼。每次代碼發生改變,你都需要修改註釋。而其實代碼本身應當足以說明這個問題。如果代碼不能反映自己的意圖,即使是再多的註釋也不足以讓你理解代碼的所有機制,除非你把代碼的每一句話都加上註釋。甚之,這種重複的責任使得一旦註釋和代碼發生不一致,它反而會阻礙你對代碼的理解。而任何一個程序員都不願意寫太多的註釋和文檔。所以Martin fowler說:

When you feel the need to write a comment,first try to refactor the code so that any comment becomes superfluous。

Martin Fowler同時指出,Refactoring不但能夠增加別人對你代碼的理解,而且是一種非常好的理解別人代碼,學習別人代碼的方法。通常,當你拿到一大堆代碼時,你可能會覺得一片茫然,不知道從何處開始。學習別人代碼最好的方法就是對代碼進行進行Refactor。如果你發現自己不能理解一段代碼,那麼試圖使用對自己說,哦,這段代碼可能是在做什麼事情。給他一個有意義的名字,refactor它。Refactor使得你對代碼的理解不是僅僅停留在腦袋中,而是看到代碼確實按照你的理解再發生變化。如果你的refactor改變了系統的行爲,那麼說明你的理解還有問題。你必須返回重來。

Refactoring 改進軟件的設計
許多人把編程看作是一種低級活動。他們認爲代碼僅僅是設計的附屬物。然而正是代碼,而不是你腦袋裏或紙上的設計,真正驅動計算機完成你想做的事情。而絕大多數的bug也產生於編碼階段。

很多方法學認爲通過分析和設計的嚴格化就能產生更高質量的軟件,這實際上是不可能的。正如Brain Foote和Joseph Yoder在《Big Ball of MUD》一文中指出,雖然許多作者提出了很多理想上非常完美的體系結構,如Layer、PIPELINE等等。但在實踐中,幾乎從來都不能看到這麼結構清晰的系統。

這一方面是由於分析和設計一個領域的應用程序需要對該領域豐富的知識,而這種知識不是在一開始都能獲得的。我們通常需要在實踐反饋的過程中才能一步步加深自己對該領域的理解。因而,我們一開始的設計可能並不能正確反映系統的內在本質,所以也不可能在代碼中得到很好的反映。

另一方面,即使一開始的設計是完好的,隨着用戶對系統使用的深入,新的需求可能會被加入,舊的需求會被修改、刪除。一個最先的設計不可能完全預料到這些變化。

一旦實現開始偏離最初的設計,那麼它的代碼將不受控制,從而不可避免地開始腐蝕。代碼加入越多,腐蝕的速度越快。如果沒有辦法讓設計儘可能地與實現保持一致,那麼這種腐蝕的最後結果就是代碼不得不被拋棄。

但是讓代碼實現和設計始終保持一致並非那麼簡單,在傳統的軟件方法中,一旦開發到了實現階段,就很難對設計做出變化。所以最近發展的面向對象方法學把增量迭代(iterative)作爲一個基本原則。

也許是題外話,在目前最爲時行的一些"重型"軟件方法學中,我們很難找到對迭代(包括設計的迭代)明確的支持、定義和操作過程,以及如何提高程序員適應這種動態開發能力的方法。在我看來,重型的軟件方法學即使能夠對軟件開發起到一定的作用,他也不可能包羅萬象,解決軟件開發中的所有問題。開發方法學重視生命週期管理和控制,但軟件的開發並不只有過程和生命週期,更重要的是,同時往往被"正規"的軟件方法所忽略的是,軟件開發是人的活動。不管你的過程控制是多麼的嚴格,不管你的生命週期模型是多麼的完美,如果不能提高人的生產力,提高產品的質量,那麼一切都是毫無意義的。

在這裏,要實現這樣一種增量迭代的開發模型,你必須能夠讓分析人員、設計人員、程序人員、測試人員等等,所有參於開發活動的人有能力或者能夠有切實可行的方法來實現迭代,實現增量。如果不是這樣的話,你無法隨時保持實現和設計之間的一致性,無法把編碼實現中所發現的不合理設計反饋到初始設計,也無法在需求變化時對實現所產生的影響準確及時地得到反映。

如果沒有切實可行的基本方法來支持迭代中所需要的改變,那麼迭代將是非常困難的.我們可以設想,一旦新的需求到達,新的一輪迭代開始,而原先的系統設計被證明無法適應現在的變化,這個時候你如何能夠使得迭代順利地以增量的方式進行下去?

Refactoring提供了對incremental iterative development最好的支持。隨着系統的演變,代碼的結構越來越差,通常這意味着要完成一件事情需要更多的代碼。很多情況,通常緣於在幾個不同的地方都有類似的代碼。因此Refactoring最重要的課題之一就是排除重複。我們通過排除重複力求能夠達到Once And Only Once的境界。而它正是好設計的一個基本標準。Once and Only Once雖然不能直接提高軟件的效率,但卻讓代碼的修改和理解變得更爲容易、系統的結構更加清晰。它是消除代碼腐蝕的最佳途徑。

Refactoring 幫助你尋找 Bug
幫助理解代碼同時也可以幫助你發現bug。很多代碼處於系統中一些非常微妙的地方。如果你只是一遍又一遍地閱讀代碼,恐怕你永遠也找不到bug。有的時候,你使用IDE提供的工具也難以跟蹤這樣的bug。因爲如果你的代碼沒有很好的結構,譬如一個類具有太多的責任,那麼它必然具有太多的狀態,在調試程序的時候,你同樣需要注意太多的現象。

你可以用refactoring使得程序代碼的結構更清晰,每一個時刻可以更集中關注專一的數據和行爲,這會使你的工作量大大減少。同時,由於refactoring要求small steps,並且對每一步都進行嚴格的測試,這樣會使得bug很容易地浮現出來。

Refactoring 讓你編程更快
在瞭解refactoring後,你可能承認refactoring能夠改進軟件的質量、設計、結構、可讀性,減少bug,但是你會認爲運用refactoring技術進行軟件開發有可能減慢你的開發速度。畢竟,你要編寫額外的單元測試,你要去refactor的代碼本來就能夠工作的代碼。

那麼,爲什麼要如此麻煩?他不會拖我的進度嗎?

事實上,Refactoring確實能夠加快軟件的開發速度。一個好設計的基本前提就是允許更快的軟件開發。說得更絕對一點,好設計的全部就是它是否能夠更快、更靈活地支持軟件的變化。如果沒有一個好的設計,一開始你可能可以開發得很快,但是隨着功能的增加,你的代碼逐漸腐蝕,結構漸漸失去。每次當你需要加入新功能時,你必須花大量的時間去理解原來的代碼,修改原來代碼的bug。改變一項功能需要花費越來越長的時間。

Refactoring支持好的結構、設計和理解性,它讓你更快地開發軟件。因爲它可以防止軟件的侵蝕,他甚至用於改進設計。

 

發佈了27 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章