2017-07-18 47 views
2

我正在存儲和解析xml文件,這些文件隨着時間的推移而演變,所以當存儲時我也存儲格式的版本。多種版本的類/算法的設計模式

當我加載一個XML我得到的文件的版本,並基於這個版本我使用特定的Java類來處理它。 xml格式每隔幾周就會更改一次,因此正在創建一個新類並將其添加到類列表中。我可以隨時加載任何版本的xml(例如,今天我可以加載兩年前創建的版本爲v02的xml文件,而當前版本爲v26)

是否有這種問題的設計模式?有這種問題使用依賴注入的設計模式嗎?

目前我有一個Java接口限定DocumentParser和我有每個在不同的包數DocumentParsers(例如com.parsers.v1.DocumentParserImpl),我有一個提供者類DocumentParserProvider使用的版本(例如public DocumentParser get(String version);),以提供適當的解析器。界面API永遠不會改變,那就是我們總是從我們的界面問同樣的事情。

有沒有更好的方法來做到這一點或有沒有這個問題的名稱?

+0

正如你在問題中提到,依賴注入的設計模式。 –

回答

0

這聽起來像是一種策略模式,因爲您希望使用不同的Loader類實現來加載不同的XML文件。

您可以通過逐個應用程序啓動實例化多個Loader實例(或一次反射),並將它們存儲在工廠中。然後,您可以要求工廠根據XML版本爲您提供Loader


如果你想使用DI,你可以有一個Map<String, Loader>對象,簡單地映射XML的,其裝載機的版本。

+0

謝謝,我已經使用工廠(DocumentParserProvider)實現了它。我對我的班級的組織有點擔心。我爲每個Loader(DocumentParser)使用了不同的包,而且我已經有了29個。有沒有關於這個或者更明智的方法的最佳實踐? – awkwardarts

+0

那麼,我建議他們保持這樣的狀態:將'Loader'接口保存在'com.yourcompany.yourapp.xmlloader'包中。然後創建像「com.yourcompany.yourapp.xmlloader.fooloaders」和「com.yourcompany.yourapp.xmlloader.barloaders」這樣的子包。您還可以提供'Loader'接口'StandardLoader'的默認實現,或者乾脆做一個實現了通用代碼一個抽象類,但公開受保護的抽象函數提供的方法去做定製...百萬:) – Jay

+0

@awkwardarts這29個班級之間有什麼不同?重複多少?應用DRY原則。在文本工具中查看diff的內容;也許你可以看到經常發生的變化。戰略模式假定每個實現都像一個獨立的插件,但您不必這樣做。一種極端的編程方法可能是爲每個版本提供一個switch case語句。如果模塊化分解加載函數,可能會更容易維護。重複是許多重構適用的代碼氣味。戰略不過是其中之一。 – Fuhrmanator

0

根據參與實際分析的步驟,你也可以申請Template Method pattern(與策略):

enter image description here

這是一種像將不重複自己(DRY)和重構將共同部分解析到模板方法中,併爲變化的部分定義多態方法。適用於您的解析器的背景下:

enter image description here

如果大部分重複的代碼被隔離於模板的方法,你可以停在那裏。正如我在對@ Jay的回答的評論中所寫的那樣,您應該先看看是否存在某種模式,即每個XML文件版本中的不同模式以及它如何影響解析。你可以

  • 定義parseOperation本只是傾向於改變部分(提取方法重構),用模板法parse在適當的時候調用它們。
  • 更進一步,看看parseOperation本身是否重複。如果是這樣,那麼將重複的代碼放入其他類中(提取類重構以使用合成)。理想情況下,如果發生任何複製/粘貼重複,請將其提取到某種ParseUtility類中(或者它可能是抽象類中的靜態函數,具體取決於您如何測試/重用它們)。

這種重構方法看起來像很多工作,具體取決於對XML文件的版本進行了哪些更改。在錯誤修復的情況下,投資可以得到回報。例如,僅使用策略(沒有該重複部分的重構),如果你發現v1一個錯誤,你必須解決它,那麼你可能結業不必重複錯誤修復ñ倍,在其他版本之後(因爲存在該錯誤的代碼被複制/粘貼)。

在重構後的版本,很少或根本沒有重複,如果bug是在ParseUtil.refactoredRepeatedMethod1()隔離,那麼你解決它只有一次在那裏。