2009-07-06 26 views
5

我將一個開源Java庫轉換爲C#,C#中有許多標記爲棄用的方法和類。這個項目是一個以乾淨的石板開始的機會,所以我打算完全刪除它們。但是,從事較大型項目的新人,我擔心情況會再次出現。由於大部分敏捷開發都是圍繞現在的工作進行的,如果需要進行重構,似乎API的棄用必定是一個常見問題。即使我不完全確定項目的未來方向,我是否可以採取預防性措施來避免/儘量減少API棄用?敏捷實踐避免不推薦使用的代碼?

回答

15

我不確定你能做多少事情。需求會發生變化,如果您絕對必須確保API的客戶端不會被更新的API版本所破壞,那麼您將只依賴於棄用代碼,直到您認爲沒有人使用棄用的代碼。

在代碼中放置[Obsolete]屬性會導致編譯器在引用過時的方法時創建警告。這樣API的客戶端,如果他們努力修復他們的編譯器警告,可以逐漸轉向新的方法,而不會讓所有的東西都破壞新版本。

它的有用的,如果您使用ObsoleteAttribute的覆蓋,這需要字符串:

[Obsolete("Foo is deprecated. Use Bar instead for munging widgets.")] 

<輕浮>

也許你可以創建一個TimeBombAttribute:

[TimeBomb(new DateTime(2010,1,1), "Foo will blow up! Better use Bar, or else."] 

在你的代碼,反映對於具有timebomb屬性的方法,如果在指定日期之後調用它們,則拋出KaboomException。這將確保在2010年1月1日之後沒有人使用過時的方法,並且可以很好地清理您的API。 :)

< /輕浮>

+0

+1:API更改是常態,不是一個例外。如果API沒有改變,那麼你的代碼庫就已經死了,沒有人關心如何適應新的目的。 – 2009-07-08 14:35:03

5

馬特說,該Obsolete屬性是你的朋友...但每當你應用它,提供瞭如何更改調用代碼的細節。這樣你就可以更好地改變人們。您可能還想考慮指定您希望刪除哪種版本的方法(可能是下一個主要版本)。

當然,您應該努力確保您不要調用過時的代碼 - 特別是在示例代碼中。

0

我認爲代碼的貶低是不斷重構和增量開發等敏捷過程的不可避免的副產品。因此,如果您在處理項目時最終得到棄用的代碼,那不一定是壞事 - 只是生活中的一個事實。當然,你可能會發現,不是貶低代碼,而是保留大量的代碼,但將其重構爲不同的方法,類等等。

因此,底線:我不會擔心在敏捷開發期間不推薦使用代碼。如果它在一段時間內達到目的,那麼你做的是正確的事情。

1

馬特的回答是堅實的建議。我只是想提一提,intially你可能想使用的線沿線的東西:

[Obsolete("Please use ... instead ", false)] 

一旦你的代碼移植,假更改爲true,然後編譯器會把所有的方法調用一個錯誤。

2

由於大部分敏捷開發的,如果需要

這不是敏捷圍繞着使現在的東西的工作和重構之後。這是在敏捷標籤下僞裝的牛仔編碼。

理想的是,無論你完成,是完成,根據任何定義你做。國防部通常會沿着「重構功能推動,測試和相關代碼」的方式陳述某些事情。當然,如果你正在研究一次性原型,你可以有一個更放鬆的國防部。

API修改是一個困難的野獸。如果它們只是您正在修改的項目內部API,最好的方法是儘早重構。如果您需要更改內部API,請繼續並同時更改所有API客戶端。通過這種方式,重構債務不會變得非常大,您不必使用棄用。

對於已發佈的API,您可能需要維護一些源代碼和二進制兼容性,至少要等到下一個主要版本發佈時爲止。在維護兼容性的同時,標記舊API不再適用。與內部API一樣,您應該儘快修復內部代碼,以免使用棄用的API。

1

關注喬希布洛赫的「How to Design a Good API and Why It Matters

最重要的是W/R/T折舊是知道「有疑問時,離開它。」觀看視頻以獲得澄清,但這與必須支持永久提供的內容有關。如果你真的期望這個API被重用,那麼你就是在有效地設定你的決定。

我認爲API設計以敏捷的方式來做是一件非常棘手的事情,因爲您期望它可以以許多不同的方式重用。您必須擔心打破依賴於您的其他人,因此儘管可以完成,但如果沒有從其他團隊快速轉向,正確的設計就很難實現。當然,這裏的棄用會對此有所幫助,但我認爲YAGNI在涉及API時是一種更好的設計啓發式。

1

API設計的經驗法則是關注它的功能,而不是它如何實現。一旦你知道最終目標,找出你需要的絕對最小輸入並使用它。避免將自己的對象作爲參數傳遞,只傳遞數據。

從執行中分離配置。例如,也許你有一個圖像編碼器/解碼器。

而是撥打電話一樣的:

Encoder.Encode(bytes, width, height, compression_type, compression_ratio, palette, etc etc); 

讓它

Encoder.setCompressionType(compression_type); 
Encoder.setCompressionType(compression_ratio); 
etc,etc 
Encoder.Encode(bytes, width, height); 

這樣,添加或刪除設置是不太可能打破現有的實現。

0

對於棄用,基本上有3種類型的API:內部,外部和公共。

內部是當你的團隊唯一的代碼工作。貶低這些API並不是什麼大不了的事情。你的團隊是唯一使用它的團隊,所以他們不會長久,有改變他們的壓力,人們不害怕改變他們,並且人們知道如何改變他們。

外部是當它有相同的代碼庫,但不同的團隊正在使用它。這可能是一家大公司的一些通用庫,或者是一個流行的開源庫。關鍵是,人們可以選擇他們編譯的代碼版本。棄用API的難易程度取決於組織的規模和溝通程度。國際海事組織,它的反對者的作業更新舊代碼,而不是標記它已棄用,並讓警告飛過整個代碼庫。爲什麼棄用者而不是棄權者?因爲這位記者是知道的;他們知道變化和原因。

這兩種情況很簡單。只要有向後兼容性,通常你可以做任何你想做的事情,自己更新客戶端,或者說服維護者去做。

然後有公共api的。這些基本上是外部API,客戶端沒有太多的控制權,比如web API。這些難以置信地更新或棄用。大多數不會注意到它的破壞,不會有人來修復它,不會得到它的變化的通知,並將只有修復它一旦它的破壞(他們已經大吼打破它,當然)。

我不得不做上述幾次,這是一件很麻煩的事情。我認爲你能做的最好的是有意破壞它,等一下,然後恢復它。當然,你首先發出通常的警告和棄用聲明,但是 - 相信我 - 在事情中斷之前什麼都不會發生。

我還沒有嘗試的想法是讓人們註冊運行小測試的簡單應用程序。當您想要進行API更新時,請運行外部測試並聯系受影響的人員。

0

另一種流行的方法是讓客戶依賴(網絡)服務。這裏有一些構造允許你爲你的服務進行版本管理並允許客戶執行查找。這增加了更多移動部件和複雜度,但如果您正在考慮翻譯大量版本並且必須支持生產中的多個版本,這會有所幫助。

This article做了很好的解釋問題和方法。