複数のファイルタイプがあるとしましょう:
.json, .csv ... etc
これらのファイルタイプにはさまざまな形式があります。
これらのファイルからフィールドを抽出する必要があります。ただし、1つの形式にすべて同じフィールドがない場合があります。
フィールドはファイル形式間で共有されることがあります
結果は、ファイルに要求されたフィールドがある場合は返され、そうでない場合はフィールドが存在しないという通知が送信されます。
新しいフォーマットや新しいフィールドを追加できるようにコードを拡張できるようにすることを目指しています。
これに正しい方向を示す可能性のあるデザインパターンはありますか?良いデザインを思いつくのに苦労しています。
さまざまなファイルタイプ(csv、json ..etc)をロードするための戦略パターンを使用することを考えていましたが、任意のフィールドを抽出すると失われます。
各ファイル形式に同じフィールドがある場合、これは簡単です。おそらく私はオブジェクトをまとめるのに一生懸命努力していますか?
ここで使用する基本的なことは、パターンに関係なく、モデル化するもの、つまりファイルに含まれるものやアプリケーションに必要なものを決定することです。
どちらのユースケースもあります。テキストエディタは.jsonまたは.csvのいずれかを問題なくロードできますが、任意のフィールドとその値を表示できますが、表示する以外に何をすべきかわかりません。テキストエディタは、ファイルを理解せずに逆流しているだけです。アプリケーションでも同じことができます。この状況では、フィールドに対してロジックを実行しません。ファイル形式を検出し、その形式に従ってファイルを提示します。異なる形式を異なる方法で提示する場合は、戦略が適切に機能します。ここでは、ユーザーが任意のフィールドを理解できるようにします。
一部のビジネスロジックで任意のフィールドを使用する必要がある場合は、別の状況にあります。いくつかの適格なフィールドが存在し、それに対して実行するロジックが存在し、それを処理する方法が存在しないことを期待しています。ファイル形式を検出して処理する必要があり、戦略は引き続き機能しますが、この任意のフィールドを理解し、ファイル形式に関係なく、すべてのビジネスで同じように機能するアクセス可能なデータ構造を構築する必要があります。この任意のフィールドに対して実行しているロジック。
この後者の場合、1つの補助フィールドのみが必要になることはまれであることを理解しておくと役立つ場合があります。通常、1つの一貫したアイデアを形成するためにグループ化できるものがいくつかあります。これらのグループのいくつかが1つのファイルに含まれている可能性があります。これらのグループは、データ構造、データ転送オブジェクト、POJOになります。彼らが単に彼ら自身の価値を超えたアイデンティティを持っているならば、彼らは実体になります。
ファイルからメモリにデータを取得するのは簡単ではありません。ファイルがメモリ内で必要なものに厳密に従っているため、単純な場合もありますが、常にそうであるとは限らず、いくつかの変換を行う必要があります。データベースでこの問題が発生した場合、それは オブジェクト-リレーショナルインピーダンスの不一致 と呼ばれます。
それにもかかわらず、コードが任意のフィールドを理解する必要がある状況では、ファイルを無視してアプリのニーズに集中することから設計を開始するのが最善です。フィールドが存在する場合は、何らかの方法でフィールドを取得するとします。何かに渡されるようにして、必要であることを表現します。必要に応じて使用してください。
それがすべて完了したら、それを見つけて必要な場所に渡すコードを記述します。このための良いテクニックは、依存性注入です。これにより、任意のフィールドの使用を、モデル化に使用するデータ構造の構築から分離できます。
これに対する魔法の解決策はありません。ファイル形式にいくつかのバージョン情報が組み込まれている場合は、そのデータを使用してファクトリにフィードし、読み取り用のストラテジーの適切なインスタンスを作成できます。また、そのデータを処理するための個別の戦略がある場合もあります。それらの間でロジックを共有できる程度は、それらを中心にシステムを構築するために(アプリケーションの機能に関する知識に基づいて)思いつくことができる有用な抽象化の数によって異なります。
Strategyパターン、および実装の詳細に依存しない必要があるその他のパターンの背後にある中心的な考え方は、抽象化(インターフェイスなど)に対してコードを記述し、他の実装固有のオブジェクトにその抽象化をサポートさせることです。
十分に一般的であると同時に、アプリケーションが必要な作業を実行できるように十分に役立つインターフェースを考え出す必要があります。これは、上位レベルでは、一意である可能性のあるデータフィールドを参照できないためです。特定のファイル形式とバージョン(または構造、順序などの他の形式固有の詳細)に変更します。そうしないと、それぞれのケースを異なる方法で処理する必要があり、拡張性と保守性が制限される可能性があります。アイデアは、このフォーマット固有の動作を下位レベルのクラス、または関連するクラスのコレクションに含めることです。したがって、アプリケーションが何をするのか、そしてロジックをより高いレベルの用語で表現できるかどうかを考える必要があります(つまり、コードDoATask()に指示して、フォーマット固有のサブクラスに処理させることができるはずです)。 、ReadDataField(...); DoStuffWithDataField(...);)の代わりに。
別の可能なアプローチ(上記で説明したものを補完する可能性があります)は、アプリケーションが内部で使用するある種の統合データモデルを考え出すことです。さまざまな形式固有のデータリーダーがデータを読み取り、それをこの統一された形式に変換し、アプリケーションの「コア」がそれを取得します(その形式のデータでのみ機能します)。これには、(内部形式との間で変換するための)定型コードを記述する必要があり、パフォーマンスが低下する場合と発生しない場合があります。ただし、設計はトレードオフがすべてであるため、長所と短所を自分で比較検討する必要があります。
P.S.利用可能なバージョン情報がない場合は、ドメインに関する知識を使用して、ファイルを何らかの方法で検査し、ファイルの構造などに基づいてファイル形式を決定(推測)できる可能性があります。ただし、これは(1)常に可能であるとは限らず、(2)可能であっても、信頼性が低く、裏目に出る可能性があります。