2009-12-29 98 views
10

在我工作的項目中,我們處理醫療帳單。支持向後兼容的類版本化

每次國家對官方表格(我們的數據類表示)進行更改時,爲了保持與以前表格的向後兼容性,我們添加了新的屬性,但保留了舊的屬性,並且保留了舊的屬性,並且擁有文檔版本屬性,用於確定完成了哪些驗證以及用於顯示它的UI操作。

這導致項目生命週期中的類型臃腫(近5年的國家授權更改),並且根本不支持舊文檔格式不是一種選擇。

我想嘗試爲每個文檔版本創建一個新類,但即使如此,我們仍然會有幾個非常相似(儘管稍有改動)的代碼副本。而諸如ProgressNoteV16,ProgressNoteV17等類名稱看起來很可怕。

繼承無法使用,因爲這仍然會導致相同的問題(具有不再需要的屬性的類)。接口會使接口臃腫,這不會解決問題。

用於解決此問題的解決方案和最佳實踐是什麼?

回答

7

對於以任何身份與公衆一起工作的任何機構來說,這是一個相當經典的問題,特別是在政府或政府監管機構的情況下。解決方案不是微不足道的,它可能需要一些重要的工作來創建,以及事後維護。

在過去,當我爲客戶處理類似問題時,這對我來說很有效,但它可能不適用於您,但您需要起草您嘗試完成的內容,以及是否有意義執行此操作。

有一對夫婦的模式來熟悉(如果你的arent的話):

  1. Factory這已是前面提到的
  2. Composition希望這將讓你出的一些醜陋的遺傳問題
  3. Template用於分離出表格與版本之間的邏輯關係

有兩本書是爲解釋這些相當不錯(和一些其他有用的):

  1. Head First設計模式(不記得了我的頭頂部)企業應用架構的
  2. 模式(福勒)

我們我已經在過去使用的過程:

  1. 開始採取所有當前的版本形式,將它們分成不同的類別並尋找共同的重疊。您可以在草稿模式下或按照您當前的計劃對每個版本使用不同的類別
  2. 從此類結構衍生出許多「基本」對象,您可以將它們用作每個重要版本集的繼承根表單。你可能有其中幾個,但它們應該少於你的總表單對象。
  3. 現在,在每個這些基礎對象中,將通用功能(即名稱和地址結構等)組合在一起並將其抽象到其自己的類層次結構中,通過構造函數注入將此hieararchy注入到基類中。
  4. 現在將組合模式應用到您的基類層次結構中,並努力獲得儘可能多的常見類結構。理想情況下,此時您的表單將只是在每個表單中發生更改的最小功能,並且具有一個構造函數,可以使用所有常見(也許稍有不同)的功能。
  5. 現在應用模板模式從您的類中抽象出所有常見「功能」,例如常見驗證和持久性邏輯,再次使用構造函數注入以將此功能返回到您的基類中。從基類
  6. 提取接口適配器定義和使用這些爲基礎,您的應用程序在你的表單工作
  7. 建立你的工廠類來處理這一設置的所有蹩腳的工作。

希望能給你一些想法。

+0

謝謝你,我們有因道路潛力大修重新思考我們的設計能力,聯邦政府正在做的事情。這個大綱將大大有助於探索可能性。 – 2009-12-29 21:21:10

+0

NP。祝你好運。如果您有能力接觸到一些其他機構如美國國土安全部(人類服務)或DIS(移民局)他們有大規模這個問題,或許能爲您提供一些好的信息。 – GrayWizardx 2009-12-29 21:51:06

+0

我碰到這來是因爲我開始看到「日期」出現在我們的類名,即ClassA的,ClassA20100901,ClassA20101201。有人向我解釋爲:ClassA的有效期/使用,直到9月1日,然後Class20100901將被使用,然後在12月1日最後一堂課變得活躍。這是一種巨大的氣味,有些事情是錯誤的。我會消化這個並且向團隊提出這個建議。我會提供一個答案,如果我們找到任何提示。謝謝! – 2010-08-05 19:21:47

2

如果由於文檔中的字段可以被刪除而無法使用繼承,那麼目前如何處理?

根據您的設計細節,您應該能夠覆蓋當前版本文檔未使用的字段(即覆蓋該文檔的子類),並在該方法的實現中引發NotSupportedException或類似事件如果表單試圖分配一個值。通過類似的邏輯,你可以(也可能應該)使用接口......只是知道一個具體的實現可能會爲它實現的一個屬性拋出一個異常,但是這個屬性並沒有爲該UI的版本定義。

您可以使用Factory Pattern爲給定的表單版本返回適當的對象實例。

如果代碼之間存在一些共同點,但代碼稍有變化但大多相同,則可以將某些共同性重構爲由多個公共方法使用的私有/受保護方法。

至於類命名,如果使用Factory Pattern,則可以使用該接口在大多數代碼中引用該類。只有工廠本身需要處理「奇怪」的類名稱。

+0

「如果由於文檔中的字段可以被刪除而無法使用繼承」,那麼目前該如何處理?「 那將不能解決的有太多的特性(從留在向後兼容以前的版本) – 2009-12-29 20:45:06

+0

工廠模式似乎像一個合理的解決方案類的問題,因爲數據綁定接受字符串將不會有強類型編譯器錯誤...... – 2009-12-29 20:47:21

+0

@Aequitarum:UI的特定版本大概不會綁定到不適合該版本領域具有特定版本的子類,拋出一個NotImplementedException如果一個這樣的屬性由UI綁定到所有幫助後。趕這樣的問題早。 – 2009-12-30 00:49:55

0

我會以一種更鬆散耦合的方式來實現它 - 一個包含兩個字段的類:一個版本和一個字典。當數據發生變化時,嘗試跟蹤丟失和添加的屬性變得非常繁瑣。使用字典,您可以簡單地測試以查看密鑰是否存在。