1

XML メッセージをビジネス オブジェクトに解析したいとします。プロセスを次の 2 つの部分に分けます。

-XML メッセージを XML 文法オブジェクトに解析します。-XML オブジェクトをビジネス オブジェクトに変換します。

最初の部分は自動的に行われ、各ノードの文法オブジェクトが生成されます。

2 番目の部分は、これまでの XML アーキテクチャに従って行われます。例:

XML メッセージ (簡略化) がある場合:

<Main>
  <ChildA>XYZ</ChildA>
  <ChildB att1="0">
     <InnerChild>YUK</InnerChild>
  </ChildB>
</Main>

次のクラスを見つけることができました。

DecodeMain(Calls DecodeChildA and B)
  DecodeChildA
  DecodeChildB(Calls DecodeInnerChild)
     DecodeInnerChild

主な問題は、同じメッセージのバージョンを処理する必要がある場合に発生します。DecodeInnerChild のみが変更される新しいバージョンがあるとします (例: 値の末尾に「a」を追加する必要があります)。

ソリューションが今後のバージョンに対応し、可能な限りクリーンであることが非常に重要です。次のオプションを検討しました。


1) 単純な継承: DecodeInnerChild の 2 つのクラスを作成します。バージョンごとに 1 つ。

欠点: 適切なクラスを呼び出すには、親クラスごとに異なるクラスを作成する必要があります。


2) バージョン パラメータ: バージョンをパラメータとして持つオブジェクトを各メソッドに追加します。このようにして、各バージョンに応じて各メソッド内で何をすべきかがわかります。

短所:まったくきれいではありません。異なるバージョンのコードが混在しています。


3) 継承 + バージョン パラメーター: 直接変更されるノード (InnerChild など) の共通コードの基本クラスを持つ 2 つのクラスを作成し、各メソッドのパラメーターとしてバージョンを追加します。ノードが別のクラスを呼び出して子オブジェクトをデコードする場合、Version パラメータに応じていずれかのクラスが使用されます。


4) ある種のエグゼキュータ パターン (やり方がわからない): 最初に、使用されるすべてのメソッドが示されているある種の仕様オブジェクトを定義し、このオブジェクトをクラスに渡します。それらの実行を担当します。


どのようにしますか?他のアイデアを歓迎します。

前もって感謝します。:)

4

1 に答える 1

2

どのようにしますか?他のアイデアを歓迎します。

自分で XML を解析するのではなく、最初のステップとして、CodesynthesisXSDのようなものに必要なすべてのクラスを生成させ、それらに取り組むようにします。後でパフォーマンスや何かの問題が発生すると、より効率的なパーサーを探し始め、それが実りがない場合にのみ、特定のケース用に独自のパーサーを設計および作成し始めます。

編集:

申し訳ありませんが、もっと具体的に書くべきでした:P、最初の部分は自動的に行われ、コード全体が XML スキーマから生成されます。

では、ソフトウェアの進化に伴い、最終的に入力も進化するという通常の状況を処理する方法について説明しましょう。ここにすべての銀の弾丸と魔法の杖をテーブルに置きます。それらを実装するかどうか、および何を実装するかは完全にあなた次第です。

  1. とにかく、私が作成するほとんどのものにはバージョン属性があります。エレガントに解決できない下位互換性の問題をに持つのは正気です。最も重要なことは、古いソフトウェアが新しい入力の解析に失敗した場合に、誰もがすぐに理解できる苦情を生成することです。
  2. 通常、コンバーター用のインターフェースも追加します。そのため、古いソフトウェアは、それを解析できない場合に、新しいバージョンの入力からのコンバーターを装備できます。また、新しいソフトウェアは同じコンバーターを使用して古い入力を解析できます。さらに、完全に「エイリアン」入力からコンバーターを接続する場所です。ウィン・ウィン・ウィンの状況。;)
  3. DecodeInnerChildマイナーな変更の特別なケースでは、新しいものを内部的により柔軟にするのが安価であるかどうかを検討し、最終的に「a」の有無にかかわらず値を有効として受け入れます。コンバーターでは、古いバージョンに変換するときに、その「a」を取り除く必要があります。
  4. 多くの場合、実際にInnerChildは分割され、両方のバージョンが並べて使用されます。2 つの の間に十分な動作の違いがある場合InnerChildは、 polymorphic を避ける必要はありませんInnerChilds。ポリモーフィズムが追加されると、実際にあなたが1で言うように、そのようなポリモーフィックメンバーを持つすべてのクラスを含むクラスを変更する必要があります。コンバーターは通常、そのような場合に、不自由を生成するかInnerChild、入力が能力を超えている古いバージョンに転送する必要があります。
于 2012-10-27T22:24:57.220 に答える