2つのデータソース間の密結合を減らす方法


10

次のアーキテクチャの問題に対する適切な解決策を見つけるのに問題があります。

この設定(下図)には2つのデータソースがあり、データソースAはタイプFooのアイテムのプライマリソースです。Fooの追加情報を取得するために使用できるセカンダリデータソースが存在します。ただし、この情報は常に存在するとは限りません。

さらに、データソースAを使用してタイプBarのアイテムを取得できます。ただし、各バーはFooを指します。ここでの問題は、各バーがFooを参照する必要があることです。Fooには、データソースBによって拡張された情報も含まれます。

私の質問は、SubsystemA.1とDataSourceBの間の密結合を取り除く方法ですか?

http://i.stack.imgur.com/Xi4aA.png


10
それは美しいスケッチです。それを描くのにどんなプログラムを使いましたか?
Marcelo MD

それを描くのにどんなプログラムを使ったのかも知りたいです。お願いします。
TulainsCórdova

2
yuml.meは、彼が図を作成する可能性が非常に高いサイトです。
Jason Turner

1
されていないDataSourceADataSourceB切り離さすでに?およびのDataSourceA両方に依存しますが、には依存しません。SubSystemA.1SubSystemA.2DataSourceB
TulainsCórdova

1
@fstuijtいいえ、違います。SubsystemA.1以外のものを使用するように変更してもDataSourceBDataSourceAわかりません。メソッドがあるDataSourceAことだけが気になります。との間には抽象化があります。SubsystemA.1getFoo(id)DataSourceADataSourceB
TulainsCórdova

回答:


3

その背後にあるのとほとんど同じデータアーキテクチャでアプリを作成しました。自動化と内部の日々の情報のほとんどが含まれるオンサイトSQLデータベースがあり、次に販売、アカウント管理、現場担当者などに使用されるサードパーティのクラウドサービスがあります。ヘルプデスクはクライアントの物理的な場所に関する両方の情報を必要としていましたと機器、そして私が介入するまで2つの異なるアプリケーションからそれを得ていました。

長い点と短い点は、一方のデータソースが他方のレコードへの参照を持つ必要があるということです。私たちの場合、サードパーティのクラウドデータにはオンサイトデータへの参照が含まれています。これで、どちらかのデータソースからのレコードのIDを使用して、両方からデータを取得できます。クラウドIDを使用して、クラウドからレコードをプルし、オンサイトIDを取得して、オンサイトデータをプルします。オンサイトIDでは、そのIDに基づいて両方のデータソースをポーリングします。

私のシステムでは、ドメインレイヤーでどちらのオブジェクトも他方の子にすることはしませんでした。両方のストアのデータを使用する場合は、2つのオブジェクトインスタンスを維持する必要があります。どちらも存在することが保証されていないため、そのようにしたのです。アプリは、クラウドデータ、オンサイトデータ、またはその両方でのみ機能し、データが少ないほど制限が多くなります。

ただし、特に片側が常に存在することが確実な場合は、変更するのは難しくありません。データが常に存在する側を表すオブジェクトに、他のデータストアのレコードを表すオブジェクトタイプのプロパティを含めるだけです。2つのグラフを1つにさらに高度に「マージ」することが可能です。

この種の配置は、必ず何らかのレベルで結合する必要があります。両方のデータストアとインターフェイスできるDALを用意するか、データストアごとに1つずつDALをセグメント化して、コントローラーなどの上位レイヤーにそれぞれからデータを取得してスナップさせることができます。しかし、あるレベルでは、プログラムには、これら2つの異なるデータソースのデータをまとめる賢い機能が必要です。

ほとんどの場合に必要な結合を減らすには、データの取得元の詳細を抽象化します。生成されたクラスのインスタンスとして提供されるWebサービスからデータを取得する場合は、コンバーターを配置して、サービスクラスのディープコピーをユーザーが制御するものに作成します。データの場合、変更する必要はありません。ソースはそうします(スキーマがそうである場合のみ)。

さて、これは大きな仕事になる可能性があります。私たちが使用するクラウドには数十のドメインクラスがあり、そのうちのいくつかは数百のデータフィールドを持っています-ここでキッカーです-別のクラウドまたは他のリモートへの移動に対応するために、抽象データ型に大きな変更を加える必要があります情報元。そのため、私は気にしませんでした。生成されたWebサービスドメインを直接使用し、クラウドからオフサイト(ただし、私たちの管理下にある)データストアへの変更が迫っています。詳細はまだ不明ですが、フォームを変更することを計画しています。新しいスキーマやデータオブジェクトを反映するために、データが「結合」されるアプリの分離コード。それをどのようにスライスしても、それは大きな仕事です。


この回答は私が遭遇した問題を最もよくカバーしており、私の意見ではこれまでのところ最良の回答を提供しています。ただし、複数のソースからのデータを組み合わせるのはよくある問題だと思います。役立つと思われる設計パターンはありますか?
fstuijt 2012年

1
Factoryパターンのいくつかのバリエーションが役立つ場合があります。CloudInvoiceとSqlInvoiceオブジェクト(それぞれのデータソースから)があり、単一の統合された請求書を作成する場合は、作成しようとしているレコードの各半分を取得するために両方のデータソースについて十分に理解しているファクトリを作成します。情報をドメインクラスにマージします。
KeithS、

4

これに対処する1つの方法は、1つの場所に両方のデータソースからのデータを含む集約データソースを作成することです。ジョブは定期的に実行され、ソースAとの変更をチェックしB、「デルタ」を集約データソースに書き込みます。これにより、2つの密結合データソースが1つのコヒーレントデータソースに変換されます。

いくつかの理由で、このアプローチをとることができません。

  • データの量が法外かもしれの完全なコピー- AB容量の要件を倍増、行われる必要があります。
  • データはライブです -ソース内のデータが変更されてから、集約ジョブがそれを集約ソースに伝搬するまでの期間があります。
  • データを元のソースと一致させる必要があります -この方法を使用すると、変更を元の場所に戻すタスクがはるかに複雑になります。

私は同意し、抽象化レイヤーを導入することをお
勧めします

2
データをコピーせずに抽象化レイヤーを作成できます。
smp7d

@ smp7dこれはカップリングを素敵なフロントエンドの後ろに隠します。ただし、そうでないと複雑さがデザイン全体に広がるため、システムですでにそのようなことをしていると思いました。
dasblinkenlight

DB環境によっては、これを1つ以上のビューで処理することもでき、データをコピーする必要がなくなります。
Walter、

されていないDataSourceADataSourceB切り離さすでに?およびのDataSourceA両方に依存しますが、には依存しません。SubSystemA.1SubSystemA.2DataSourceB
TulainsCórdova

1

トップレベルにはFooとBarの2つのタイプがあり、トップレベルのアクションは2つしかありません:findFoo(...)findBar(...)。これがI / O層へのインターフェースです。

:データ・ソースのあなたの説明は、A上の2つの方法があることを意味findFooし、findBarそしてB上の一の方法は:findFooAuxiliaryInformation。ではfindFoo、あなたはAとBからの情報をマージする必要があります。

どのような「密結合」なのかわかりません。そこ2つのデータセットに含まれる3つのデータタイプは、次のとおりですBarFooFooAuxData。間の結合Fooとは、FooAuxData入力データに固有であり、低減することができません。しかし、その結合はfindFooメソッドにのみ現れるはずです。それがあなたにできる最高のことです。要件は単一の場所で実装されます。変更された場合は、そのコードを変更する必要があります。


0

できません。

私が正しく理解し、FooからBar来た場合dsABarsはsに属しFooます。
好ましくは、あなたが望んでいないBarに割り当てられたのFooない限り、秒Fooによって補われているFoo.enhancedInfoことから来ていますdsB

BarsをFoos に割り当てるための好みは、密結合を作成しているものです。私はあなたを特定の道へと追いやる「要求の挑戦」とみなします。

したがって、技術的な課題は、dsB特定の情報が含まれFooているdsB場合と含まれていない場合があり、利用できない場合もあります。

あなたはFoo.enhancedInfo本当にその好みがどれほど難しくて速いかを決める必要があります。その要件に基づいて、Foo+ Barオブジェクトを提供するかどうかを決定できます。拡張されFooていないものを提供できるようにすると、ロジックが複雑になり、設定が表示されるほど厳密ではないことがわかります。変異体かを決定FooFoo.enhancedおよびBarアプリケーション(s)はサポートすることができ、あなたの究極の答えを持っています。

Foo関連情報を互いに近づけるためにできることは他にもあり、それによってこれらの問題のいくつかが解決される可能性があります。質問の言い方では、データオブジェクトレベルで問題を処理しているように思われ、インフラストラクチャタイプの変更を検討できない場合があります。


もう1つの方法 'ラウンド:FooはBar sに属します
fstuijt

@fstuijt答えを少し更新します。基本的には同じままです。Bar + Fooをどのようにサーバーに接続するかを決定する必要があります。

0

データソースBのデータが独立できない場合は、可能であればデータソースAに移行することをお勧めします。

独立しているが関連している場合は、データ仮想化を検討する必要があります。これにより、アプリケーションはデータを1つのセットとして(適切な場合)不可知の方法で処理できます。プラットフォームによっては、おそらくこれを実装するのに役立つ既存のフレームワーク/ライブラリがあるでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.