2008-09-28 68 views
36

當你在一個傳統的代碼庫中工作時,將會對時間產生最大的影響,從而提高代碼庫的質量?你可以對遺留代碼庫做些什麼,這對提高質量將產生最大的影響?

  • 刪除未使用的代碼
  • 刪除重複的代碼
  • 添加單元測試,提高測試覆蓋率,其中覆蓋率低
  • 創建跨文件格式保持一致
  • 更新第三方軟件
  • 減少所產生的警告通過靜態分析工具(ieFindbugs)

代碼庫由許多開發人員在多年的專業知識水平上編寫而成,其中很多領域都未經過測試,而且有些測試不需要花費大量時間編寫測試。

回答

33

這是一個偉大的書。

如果你不喜歡這個答案的話,我能給的最好的建議是:

  • 首先,停止製造新的遺留代碼[1]

[1]:遺產沒有單元測試代碼=代碼,因此一個未知

更改傳統代碼沒有自動化測試套件到位是危險的,不負責任的。沒有良好的單元測試覆蓋率,你不可能知道這些變化會有什麼影響。 Feathers建議您採用「束縛」方法,在這些方法中,您需要隔離需要更改的代碼區域,編寫一些基本測試來驗證基本假設,通過單元測試進行小的更改,然後從中解決。

注意:我並不是說你需要停止一切,花幾個星期爲一切寫作測試。恰恰相反,只是測試你需要測試的區域並從那裏開始工作。

吉米·博加德和雷 - 休斯頓做了非常類似於這樣一個主題一個有趣的屏幕轉換: http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/05/06/pablotv-eliminating-static-dependencies-screencast.aspx

5

我會說「刪除重複的代碼」幾乎意味着你必須拉出來的代碼和抽象的它,所以它可以在多個地方使用 - 這樣,在理論上,使錯誤更容易解決,因爲你只需要修復一塊代碼,而不是許多代碼段,來修復它中的一個錯誤。

3

我可以涉及到這個問題,因爲我目前在我腿上的一個「那些」老學校的代碼庫。它不是真正的遺產,但它肯定沒有遵循這些年的趨勢。

我會告訴你的事情,我喜歡它,因爲他們的錯誤我天天來解決:

  • 文件的輸入和輸出變量
  • 重構的變量名,使他們實際上意味着以外的東西和一些匈牙利語符號前綴,後跟三個字母的縮寫,並帶有一些不太明確的含義。 CammelCase是要走的路。
  • 我很害怕改變任何代碼,因爲它會影響使用該軟件的數百個客戶,並且有人會注意到即使是最隱晦的副作用。任何可重複的迴歸測試將是一件幸事,因爲現在爲零。

其餘的確是花生。這些是遺留代碼庫的主要問題,它們真的耗盡了大量時間。

6

添加單元測試以提高測試覆蓋率。具有良好的測試覆蓋率將允許您無懼地重構和改進功能。

CPPUnit,Working Effectively with Legacy Code的作者撰寫了這本書。

向傳統代碼添加測試比從頭創建測試要困難得多。我從書中拿掉的最有用的概念是「接縫」的概念,羽毛定義爲

「一個您可以在該程序中修改行爲而無需在該處進行編輯的地方。」

有時它的價值重構,以創建接縫,這將使未來的測試更容易(或有可能在第一的位置。)的google testing blog有關於這個問題的一些有趣的帖子,大多是圍繞Dependency Injection過程中旋轉。

+0

在代碼中添加測試真的很困難,因爲最終你甚至無法接近要測試的代碼。它有點雞和蛋,沒有測試就不能重新考慮/不能重新編寫好測試 – 2008-09-28 23:10:20

2

我會說這在很大程度上取決於你想用舊代碼做什麼...

如果將無限期地停留在維護模式和它的正常工作,什麼都不做是最好的選擇。 「如果它沒有損壞,請不要修理它。」

如果工作不正常,移除未使用的代碼並重構重複的代碼將使調試變得更容易。但是,我只會對錯誤的代碼進行這些更改。

如果您計劃在2.0版本中,添加單元測試和清理代碼,你會提出

2

良好的文檔。作爲必須維護和擴展遺留代碼的人員,這是頭號問題。即使不是徹底危險的改變你不明白的代碼也很困難。即使你有足夠的幸運可以交上文檔化的代碼,你對文檔的正確性有多確定?它涵蓋了原作者的所有隱含知識嗎?它說明了所有的「技巧」和邊緣情況?

良好的文檔可以讓原作者以外的人理解,修復甚至擴展糟糕的代碼。我會採用黑客入侵的,但有充分文件記錄的代碼,我可以在一週中的任何一天通過完美而難以理解的代碼來理解。

+0

單元測試是文檔,問題是遺留代碼(正如M. Feathers在「有效地工作遺留代碼「)沒有它們。 – 2010-07-03 10:14:17

20

我使用大約50位程序員編寫和修改的傳統1M LOC應用程序工作。

* Remove unused code 

幾乎沒用......只是忽略它而已。你不會從那個投資中獲得很大的投資回報(ROI)。

* Remove duplicated code 

其實,當我修理東西時,我總是搜索重複。如果我找到了一些我放置了泛型函數或註釋所有代碼重複的情況(有時候,放置泛型函數的努力不值得)。主要想法是,我討厭不止一次地做同樣的動作。另一個原因是,因爲總是有一個人(可能是我)忘記檢查其他發生......

* Add unit tests to improve test coverage where coverage is low 

自動化單元測試是美好的...但如果你有一個大的積壓,任務本身是很難促進,除非你有穩定性問題。去參與你正在工作的部分,並希望在幾年內你有適當的覆蓋面。

* Create consistent formatting across files 

IMO格式的差異是遺留問題的一部分。它爲您提供了關於代碼編寫的人或時間的提示。這可以給你一些關於如何在代碼的那部分中表現的線索。做重新格式化的工作並不好玩,它不會給你的客戶帶來任何價值。

* Update 3rd party software 

只有在新的操作系統不支持新的非常棒的功能或版本時,才能進行此操作。

* Reduce warnings generated by static analysis tools 

它可以值得。有時候警告可以隱藏潛在的錯誤。

1

我對遺留代碼所做的最重要的事情就是圍繞它構建真正的API。這是一個20世紀70年代風格的COBOL API,我已經構建了一個.NET對象模型,以便所有不安全的代碼位於同一位置,API本地數據類型和.NET數據類型之間的所有轉換都位於同一位置,主要方法返回並接受數據集,等等。

這很難做到正確,而且我還知道它還有一些缺陷。它也不是非常有效,所有的編組都在繼續。但另一方面,我可以構建一個DataGridView,它將數據往返於一個15年前的應用程序,該應用程序在大約半小時內將其數據保存在Btrieve(!)中,並且工作正常。當客戶帶着項目來到我這裏時,我的估計是幾天而不是幾個月和幾年。

1

與Josh Segall所說的一樣,我會說出評論。我曾經研究過一些遺留在我腿上的非常大的遺留系統,我發現最大的問題是跟蹤我已經瞭解的特定代碼段。一旦我開始放置筆記,包括「待辦事項」筆記,我就不再重新計算出我已經弄清楚的內容。然後我可以專注於這些代碼段如何流動和交互。

1

我會說,大多數情況下都不要說。如果它沒有損壞,那就不要修復它。如果它被破壞了,那麼請繼續修復並改善破壞的代碼部分及其周圍的代碼。您可以使用錯誤或嚴重缺失功能的痛苦來證明改進該部分的努力和成本。

我不會推薦任何批量改寫,重構,重新格式化或放入不受實際業務或最終用戶需求指導的單元測試。

如果你確實有機會解決某些問題,那就做對吧(第一次做這件事的機會可能已經過去了,但是因爲你再次觸摸那個部件不妨做正確的時間)這包括你提到的所有項目。

因此,總之,沒有單一或只有幾件事情,你應該做的。你應該盡一切努力,但以小部分和機會主義的方式。

1

遲到了,但在使用或引用通常是功能/方法下面可能是值得做的事情:

  • 局部變量往往傾向於在傳統代碼不佳命名(而且通常是因爲其範圍當一個方法被修改時擴展,而不是被更新來反映這個)。將這些重命名爲符合其實際用途可以幫助澄清遺留代碼。
  • 即使只是略微不同的佈置方法也可以創造奇蹟 - 例如,將if的所有子句放在一行上。
  • 這裏可能有陳舊/混淆的代碼註釋。如果不需要,請將其移除,如果您絕對必須修改它們。 (當然,我不主張拆除有用的意見,只是那些障礙。)

這些可能沒有你要找的大量頭條的影響,但他們是低風險,特別是如果代碼不能被單元測試的話。