重構模式4

refactoring Patterns:第四部分  
內容:
不應 Refactoring 的場合
實施Refactoring可能碰到的阻礙以及解決方案
學習
Refactoring獲得短期效益
削減Refactoring的額外開銷
安全Refactory
關於作者
相關內容:
該系列的其他部分
合理、勇敢地運用Refactoring

石一楹 ([email protected])
浙江大學靈峯科技開發公司技術總監
2001 年 12 月

任何一種技術都不是萬能的。正象設計模式,合理的運用可以極大地提高設計的效率和美感,再不適當的場合運用就會產生所謂的反模式。我們的refactoring亦然。
但是,作爲一種強有力的設計演變工具,refactoring值得我們付出努力。不能因爲對新技術的恐懼而放棄這樣的工具,我在這裏對可能出現抗拒情緒的一些問題進行了解釋。

不應 Refactoring 的場合

程序原型
當你原型化一個系統時,你通常不在乎程序的靈活性和效率。原型的目的僅僅是爲了證明一個概念、實現一種探索,加快加深與客戶的交流。一旦原型完成,這樣的代碼就應該丟掉,重新開始正確的編寫。但是,一旦原型能夠起到演示的作用,繼續保留它並按照這樣的方式一直實現下去的誘惑將很難抵擋。你會說:"程序運行的很好,就用這一個吧!"。從原型開始的目的來看,這樣的策略最後是不會成功的。所以Foote甚至說:

    要最小化這種將原型直接變爲產品的風險,一個辦法就是選用一種特定的語言或工具來構建你的原型,而你絕不會使用這種語言或工具完成你的最終產品。

由於原型從根本來說,不會有意考慮以後的變化和程序的結構,對原型做Refactoring是不可能也是毫無必要的。

程序不能工作
如果一個程序本身還不能工作,那麼對他進行Refactoring就沒有任何意義。Refactoring保留程序的可觀察行爲,那麼Refactoring的結果還是不能正常工作的。

這裏並不排除使用Refactoring可以排除bug,但那是在程序的絕大部分主要功能已經實現的情況下。

接近底線
如果你已經接近了最後提交日期,這個時候Refactoring可能產生的效率的提高將發生在底線之後。到那時候,一切都沒有意義了。

但是這個問題可以有另外一種考慮的思路,爲什麼會出現這種情況?是因爲估算嚴重失誤還是因爲效率太低?如果效率太低,你怎樣來提高效率?Refactoring是一種提高生產力極好的方法,因爲它使設計更好,從而使得變化更快。所以,如果你發覺時間可能不夠,往往就是需要Refactoring的一個信號

實施 Refactoring 可能碰到的阻礙以及解決方案
Refactoring帶來的長期利益是每個人都能夠看到的,但是並不是每個人都願意使用它,Opdyke說:

    因此,這類技術的支持者可能會驚異於(失望於)這個世界沒有人來敲他們的門。

接着,他指出即使已經意識到長期的利益,但人們還是不情願使用這種方法的四個關鍵理由:

"我不理解如何應用你的方法 。" "你的方法只能得到長遠利益,爲什麼要在現在竭盡努力?從長遠的角度來看,我可能不再是這個項目或這個組織的一員了" 你的方法是一種開銷活動,我是受僱來編寫特性的" "如果我們應用了你的方法,我們已有的實現可能以不刻預期的方式變化或中斷。可性度和向後兼容性對我們很重要".

這些問題其實並不單單存在於Refactoring領域,在鼓勵人們設計、編寫更重用的系統時,我們也必須解決這些問題:

  1. 技術人員可能不理解重用什麼以及如何重用;
  2. 如果不能看到短期效益,技術人員不會採用提倡重用的方法。
  3. 我們必須明確支持重用的方法可能引發的額外學習曲線和其他成本。
  4. 採用支持重用的方法不應該打斷一個項目;新的實現應當和存在的系統向後兼容。

學習
要想知道如何refactoring,你必須學習。

Refactoring已經被有經驗的OO程序員成功地使用了10多年。這些程序員也把他們Refacorting的經驗反饋給了OO社團。

本文旨在爲你提供一個導引,在學習了這篇文章後,你可以沿着以下幾個方向進行深入:

  1. 要立刻開始動手進行Refactoring,你的最佳選擇就是Martin Fowler的《Refactoring: Improving the Design of Exsiting Code》,該書有一個Refactoring的分類目錄。詳細描述了70多種Refactoring方法。Martin Fowler的主頁(http://www.martinfowler.com)上還有最近擴展的一些Refactoring方法。
  2. 你需要閱讀各種好的程序代碼和設計結構,特別是設計模式,因爲設計模式可以稱得上Refactoring的終極目標之一。
  3. 你可以到網上搜索各種Refactoring工具,我將在後面介紹,學習使用Refactoring工具進行更安全的Refactoring。
  4. 如果你想學習Refactoring方面的理論,請參見我文後附上的各種參考文獻,特別是Ralph Johnson教授的文章和他弟子們的博士論文。

另外,在我的主頁www.erptao.org上,你可以:

  1. 對本文提出評論和建議,以幫助我改進;
  2. 在論壇中有refactoring方面的討論,你可以在那裏看到refactoring的一些實踐,如果你有問題,可以在那裏提出,我將盡量回答。

Refactoring獲得短期效益
如果沒有短期效益,很難讓技術人員直接看到Refactoring的效果。由於Refactoring開始於大學的研究機構和技術前沿的小公司,所以如何在工業主流軟件中應用Refactoring成爲OO社團實踐的一個重要內容。

伊利諾斯大學研究小組的CHOISE操作系統框架是這些研究的一部分。其中,CHOICE實現了對System V,MS-DOS,BSD UNIX等差別極大的不同文件系統的支持。在開發過程中應用Refactoring後,研究者指出refactoring確實能夠獲得不少短期和長期的利益。

對於近期而言,因爲排除了重複代碼,在通用代碼測試中發現的錯誤只需要在一個地方進行修改。代碼總量變小。與一個特定文件系統格式相關的代碼與適合於兩個或幾個文件系統通用的代碼隔離。

對於中期而言,來自於refactoring的抽象通常爲以後其他的文件系統提供了方向。事實上,對兩個現有文件系統的抽象不一定完全適合於第三個文件系統,但是已經存在的通用代碼是一個有價值的起點。後續refactoring應用的結果將顯示什麼是文件系統真正的抽象。框架開發小組發現,隨着實踐的推移,加入一個文件系統所需要的努力越來越少。即使後來的文件系統更復雜,開發者更加缺乏經驗。

削減Refactoring的額外開銷
對於Refactoring所造成的額外開銷,你可以這樣來看待:

  1. 工具和技術的發展使得refactoring更加自動化,能夠減少大量的手工勞動和錯誤介入;
  2. 有經驗的OO程序員報告,refactoring所造成的額外開銷完全能夠抵消採用refactoring對程序開發其他階段的提升。
  3. 剛剛開始使用refactoring,你可能會覺得有點彆扭。但一旦成爲一種習慣,你將不會覺得這是一種額外工作,你會把它當作一個好程序員開發過程自然而然的一部分。

你可以在internet上找到很多這樣的報告,後面很多內容也都談到了這個問題。

安全Refactory
保持可觀察的行爲被稱爲Refactoring的安全性。要實現安全的Refactoring,你通常有幾種選擇[William Opdyke]:

  1. 相信你自己的編碼能力;
  2. 相信專家、文獻提供的步驟能夠幫助你減少錯誤。
  3. 相信編譯器能夠捕獲你沒有發現的錯誤;
  4. 相信你的測試套件能夠捕獲編譯器沒有發現的錯誤;
  5. 相信Code Review會捕獲你、你的編譯器、你的測試套件漏掉的錯誤

各種各樣的書籍、資料、論文、期刊可以增強你的編程能力,能夠教給你更多的良好風格。Martin Fowler的《Refactoring》就是這樣一本書,他告訴我們Refactoring有非常細小的一步一步組成,每一步看起來都不起眼,但是一系列Refactoring的結果會對系統產生有力的影響。

編譯器、好的風格、測試套件、Code Review都是非常有價值的,但是所有這些方法方法都有他們的問題,編譯器根本不知道程序的動態行爲,好的風格、Code Review完全依靠人來實現,而任何一個人都會犯錯誤。測試套件也沒有辦法覆蓋所有的行爲。

所以,面向軟件社團對Refactoring的一個重要研究方向,就是定義Refactoring安全性方面的理論並實現這種理論支持下的工具。它們可以用來檢查某一種Refactoring是否能夠安全地應用到一個程序,如果安全的話,那麼就有工具來完成Refatoring。這樣做也避免了手工完成可能引起的bug。

關於作者
石一楹,現任浙江大學靈峯科技開發公司技術總監。多年從事OO系統分析、設計。現主要研究方向爲Refactoring和分析模式。你可以通過[email protected]和我聯繫。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章