web-dev-qa-db-ja.com

アイデンティティーマップパターンの制限

質問 の実装についてRuby Identity Mapパターン の実装について)==実行中のサーバーアプリで潜在的なメモリリークが発生するため、そのパターンの最初の概念。

最初はデータベースの結果をキャッシュし、同じオブジェクトの1つのインスタンスのみがメモリに存在するであることを保証することを意図していると思っていました。この最後の仮定は正しいですか?

DDD内では、エンティティの等式は同じidと同じメモリアドレスを持つことに基づいており、メモリの問題に完全に適合しますが、多くのORMを使用した後は、常に「感じ」がありました私のオブジェクトのユニークなインスタンスがあります。この仮定は危険な考えですか?通常、オブジェクトに複数のインスタンスがあることを心配する必要がありますか?または、データベースと同期していませんか?

5
SystematicFrank

この最後の仮定は正しいですか?

はい、他にどう思いますか?

DDD内では、エンティティの等価性は、同じメモリアドレスではなく同じIDを持つことに基づいているという傾向があります。

これはDDDとは関係ありません。 「データベースオブジェクト」には常に一意のキーまたはIDが必要です。通常、それらを区別するためにDBに保存される「メモリアドレス」はありません。そのため、常に利用可能なIDがあり、IDマップパターンの使用の有無に関係なく、メモリ内のオブジェクトの等価性のチェックにも使用できます。 「アイデンティティーマップ」を配置し、コンテキストで想定すると、最初に「アイデンティティーマップ」をチェックせずにオブジェクトを作成できないことを100%確認できます。実際に、idテストをメモリアドレステストで置き換えることは可能です。しかし、実際には利点は非常に小さいです。

私はいつも自分のオブジェクトのユニークなインスタンスを持っているという「感覚」を持っていました*

正直なところ、このようなことについて「感じる」ことは、何かがどのように機能するのかを知らないという別の言葉です。そして、はい、何が起こっているのかを知らずにフレームワークを使用することは、常に「危険」です(私は「エラーが発生しやすい」という言葉を好みます)。より具体的に言えば、ORMを使用するときは、ORMが「アイデンティティーマップ」や「オブジェクトキャッシュ」などの機能をすでに提供しているかどうか、およびORMが提供する機能を正確に把握する必要があります。

通常、オブジェクトに複数のインスタンスがあることを心配する必要がありますか?

これは、作成するアプリケーションの種類、ビジネストランザクションの種類、関連するレコードの数、クエリの種類などに大きく依存します。同じ「dbオブジェクト」の2番目のコピーを同時に持つ可能性があるアプリケーションの他の部分を同時に気にすることなく、ローカルスコープでデータベースからオブジェクトを作成し、それらを操作して書き戻すアプリケーションを作成することは完全に可能です。 。ただし、アプリケーションで同じ情報を常に同期する必要がある場合、これは適切な方法ではない可能性があります。

または、データベースと同期していませんか?

繰り返しますが、これは状況によって異なります。多くのアプリケーションでは、少なくとも短時間は同期が外れるのを避けることはできません(2番目のクライアントが「プッシュ」メカニズムなしでネットワーク経由でDBを変更するシナリオを考えてください)。ただし、これが許容できる期間、および特定のトランザクションが最新バージョンのデータを確実に100%保証する必要があるかどうかは、要件によって異なります。

4
Doc Brown

アイデンティティーマップは、リクエストまたはフォームごとにスコープを設定する必要があり、スコープが制限されていない必要があります。したがって、メモリは同時使用に比例する必要があり(おそらく期限切れのセッションのタイムアウト)、それを超えてはなりません。

データベースのID(例:主キー)によってIDマップにキーを設定するのが最適です。他の人々は、キーとしてビジネスキー(例:名前、住所、DOB)を使用することについて話しますが、そのアプローチには大きな欠陥があります。アドレスが変更されたときに一致しなくなりました。

アイデンティティマップはロックとは別の概念です。同時ユーザーは、変更する可能性のあるオブジェクトの個別のインスタンスを持つ必要があります。個別のインスタンスがないと、それらの個別の変更を表現したり、保存することを期待しているである楽観的ロックの「バージョン番号」を追跡することは困難です。

2
Thomas W

あなたの理解は正しいです。

IDマップは、オブジェクト指向のプログラマーが状態管理の問題に対処するのに役立つことを目的としています。彼らは、注意が払われない場合、永続化可能なオブジェクトの古いコピーを処理するプログラムのさまざまな領域を持つことになるかもしれない命令型プログラムを記述します。

基本的な同時実行の問題を検討します。アリスは特定のレコードを画面に表示します。ボブはすぐに同じことをします。アリスは自分のコピーを更新して保存し、その後ボブが更新します。プログラムがこのシナリオを考慮しない場合、アリスの変更は失われます。

同じことを考慮に入れてください。ただし、単一のプログラムの範囲内です。プログラムのあいまいなエリアAはオブジェクトをメモリにロードしますが、他のあいまいなエリアBも同じことを行います。エリアAはそのコピーを更新し、次にエリアBを更新します。内部並行性の問題を許可するのは、常にプログラムの設計です。

命令世界では、状態変化が蔓延しています。アイデンティティマップは、メモリ内の同時実行性の問題を軽減するためのパターンです。並行性の問題を回避するように設計されたプログラムでは、アイデンティティマップは不要です。問題は、命令コードのパスが予測できない可能性があり、並行性の問題が発生する可能性があるかどうか疑問に思って、それを防ぐ必要があることです-念のため

不変のデータを持つことに重点が置かれているので、これはすべて関数型プログラミングの問題にはなりません。すべてがデータ構造で表されます。各データは1回だけ表示されます( [〜#〜] spot [〜#〜] )。その世界のすべてのデータ全体を表すいくつかのより大きなデータ抽象化の一部として。 IDマップは完全に不要です。あるいは、ある意味では、関数型プログラミングの基礎全体は、アイデンティティマップを使用して構築されていると言えます。

2
Mario T. Lanza