2017-07-18 2 views
2

私はxmlファイルを保存して解析しています。これらのファイルは時間の経過とともに進化しますので、保存するとバージョンも保存されます。クラス/アルゴリズムの複数のバージョンのデザインパターン

xmlを読み込むとファイルのバージョンが取得され、このバージョンに基づいて特定のJavaクラスを使用して処理します。 xml形式は数週間ごとに変更され、新しいクラスが作成され、クラスのリストに追加されます。どのバージョンのXMLでもロードすることができます(現在、バージョンv02の2年前に作成されたxmlファイルをロードできます)。

この種の問題の設計パターンはありますか?この種の問題に対して依存性注入を使用するデザインパターンはありますか?

現在私はDocumentParserを定義するJavaインターフェースを有し、私は別のパッケージ内のいくつかのDocumentParsers各々(例えばcom.parsers.v1.DocumentParserImpl)を有し、私はバージョン(例えばpublic DocumentParser get(String version);)を使用して適切なパーサーを供給するために、プロバイダクラスDocumentParserProviderを有します。インターフェースapiは決して変更されません。つまり、私たちは常に私たちのインターフェースから同じことを尋ねます。

これを行うには良い方法がありますか、この問題の名前がありますか?

+0

あなたが質問で言及したように、依存性注入はデザインパターンです。 –

答えて

0

Loaderクラスのさまざまな実装を使用して、異なるXMLファイルをロードする場合は、戦略パターンのように聞こえます。

複数のLoaderインスタンスをアプリケーションの起動時に1つずつ(またはすべてを一度に)インスタンス化し、工場に格納することができます。次に、XMLバージョンに基づいてLoaderを提供するよう工場に依頼することができます。


あなたはDIを使用する場合は、単にそのローダーとXMLのバージョンをマップするMap<String, Loader>オブジェクトを持つことができます。

+0

ありがとうございます、私はすでに工場(DocumentParserProvider)を使って実装しています。私は自分のクラスの編成について少し心配しています。各ローダ(DocumentParser)ごとに異なるパッケージを使用しましたが、すでに29があります。これを行うにはベストプラクティスか、よりスマートな方法がありますか? – awkwardarts

+0

さて、私はそれらを次のように保つことをお勧めします:あなたの 'Loader'インターフェースを' com.yourcompany.yourapp.xmlloader'パッケージに入れておきます。次に、 'com.yourcompany.yourapp.xmlloader.fooloaders'や' com.yourcompany.yourapp.xmlloader.barloaders'のようなサブパッケージを作成します。 'Loader'インターフェースのデフォルトの実装を' StandardLoader'として提供することもできますし、単純に共通コードを実装する抽象クラスを作ることもできますが、保護された抽象関数をカスタマイズして公開します...たくさんの方法があります:) – Jay

+0

@wkwardarts 29のクラスの違いは何ですか?どのくらい繰り返されていますか?ドライ原則を適用してください。テキストツールのdiffを見てください。多分何が変わるのかを見ることができます。戦略パターンでは、各実装はスタンドアロンのプラグインのようなものですが、このようにする必要はありません。極端なプログラミングのアプローチは、各バージョンのケースを含むswitch文を持つことです。ローダー機能をモジュール式に分解すると、保守が簡単になります。反復は、多くのリファクタリングが適用されるコードの匂いです。戦略は1つだけです。 – Fuhrmanator

0

実際の解析に必要なステップに応じて、あなたもTemplate Method pattern(戦略に関連する)を適用することができます:

enter image description here

これは一種の自分(DRY)を繰り返してはいけない適用するようなもので、リファクタリングテンプレートメソッドへの解析の共通部分を取り除き、変化する部分の多態性メソッドを定義します。あなたのパーサのコンテキストに適用される:

enter image description here

繰り返しコードのほとんどは、テンプレートメソッドに隔離されている場合は、そこに停止することができます。 @ Jayの答えに関する私のコメントで書いたように、XMLファイルの各バージョンと構文解析にどのような違いがあるかをまず調べる必要があります。あなたは

  • は、適切なタイミングでそれらを呼び出すテンプレートメソッドparseと、(extractメソッドのリファクタリングを)変化する傾向がある部分だけのためparseOperation Sを定義することができます。
  • さらに進んで、parseOperation自身が繰り返すかどうかを確認してください。そうであれば、繰り返しコードを他のクラスの中に入れます(クラスリファクタリングを抽出して合成を使用します)。理想的には、コピー/ペーストの繰り返しが発生した場合は、それを何らかの種類のParseUtilityクラスに抽出します(または、それらをテスト/再利用する方法に応じて抽象クラスの静的関数にすることもできます)。

このリファクタリングのアプローチは、XMLファイルのバージョンによって何が変更されたかに応じて多くの作業のように思えるかもしれません。バグ修正の場合には、投資は恩恵を受ける可能性があります。たとえば、戦略だけを使用して(繰り返す部分のリファクタリングなしで)、v1のバグを見つけて修正する必要がある場合は、バグ修正を繰り返す必要がありますn回他のバージョン(バグが存在するコードはコピー/貼り付けされていたためです)。

繰り返しのないリファクタリングバージョンでは、ParseUtil.refactoredRepeatedMethod1()でバグが隔離されていた場合は、一度だけ修正します。

関連する問題