12

私は、どの層がドメイン駆動型設計プロジェクトのキャッシュ(挿入/削除)作業を担当するべきかを判断しようとしています。目標は、リポジトリから取得されたエンティティをキャッシュすることによって、Webアプリケーションのパフォーマンスを向上させることです。次のようにリポジトリ、ドメインまたはアプリケーションのキャッシュに問題がありますか?

私のソリューションを分離し:

MyApp.Infrastracture 
MyApp.Repositories 
MyApp.Domain 
MyApp.WebApplication 

私はそれがキャッシュを利用のみWebアプリケーションなので、キャッシング・ロジックが行く必要があることをこの層であることを感じますか?しかし、私はWebアプリケーションを軽量に保ち、Webページを提供することに重点を置いているので、これは正しいとは感じません。

また、キャッシングはファーストクラスのドメイン概念ではないため、ドメイン層に自然に適合しません。

どうすればよいですか?

+4

これはすべて上記の問題です。キャッシングは、各レイヤーが個別に処理する必要があるクロスカッティングの問題の1つであり、アプリケーションはオーケストレーションする必要があります。 – Oded

+0

@Oded - そのコメントを回答にする必要があります。 –

+1

@David Kemp - done ... – Oded

答えて

11

これはすべて上記の問題です。

キャッシングは、各レイヤーが個別に処理する必要があるクロスカッティングの問題の1つであり、アプリケーションはオーケストレーションする必要があります。

+1

Webアプリケーションがオーケストレーターであると言えば、あなたは私を釘付けにしたと思います。 – Fixer

4

私は完全にOdedに同意します。これはクロスカッティングの問題ですが、キャッシュされたアイテムのクライアントに対しても透過的である必要があります。

例えば、リポジトリのユーザは、アイテムがキャッシュされているかどうかに気を付けるべきではありません。

キャッシングがソリューションの重要な側面である場合、ドメインではキャッシュを明確にする必要がありますが、インフラストラクチャの一部として実際に終了し、どのIoCコンテナを使用していてもかまいません。

0

複数のレベルのキャッシュをサポートするNhibernateのようなORMを使用している場合、キャッシングを複数のレイヤーに分散することができます。上位レイヤーでは、要件を基にすることができます。たとえば、ユーザーをロードするときにユーザーが実行できる機能がロードされている場合、アプリケーションレベルでキャッシュできます。したがって、すべてアプリケーションに依存します。

5

あなたは目標がリポジトリから取得され 任意のエンティティをキャッシュすることでWebアプリケーションのパフォーマンスを向上させることにある

を指摘しました。

私はあなたのリポジトリに透過的に実装する必要があると思います。リポジトリは、ドメインからの永続性の詳細を隠すためのもので、パフォーマンスのために大きなオブジェクトをキャッシュする場合は、ドメインを賢明にする必要はありません。あなたのリポジトリは、並列スレッドがオブジェクトを要求して同時にそれらを変更するのと同じ、同じオブジェクトの複数のコピーを潜在的に追跡する可能性があります。または、可能であれば、個々の集約ルートがトランザクション境界を表すときにそれらのルートへのアクセスをシリアライズします。

@Odedが指摘しているように、キャッシングは実際にどこでも発生する可能性があります。パフォーマンスが問題で、各スポットが異なる場合は、多くの場所でキャッシュを実装する可能性があります。たとえば、ドメイン内の特定のクエリの結果をキャッシュするか、HTMLレスポンス全体をキャッシュすることができます。

キャッシュがかなり漏れやすい抽象化になる可能性があるため、クロスレイヤーの調整が行われます。ドメインオブジェクトがキャッシュされている場合、キャッシュされていないのはいつですか? 1つのスレッドがキャッシュされたオブジェクトを使用していて、もう1つのスレッドがキャッシュされていないオブジェクトの場合クエリの結果をキャッシュしていて、基礎をなすオブジェクトがその後変更された場合はどうなりますか?無効化する方法と無効化する方法は、インフラストラクチャの観点とビジネスの観点から困難な質問です。古いクエリは必ずしも悪いとは限りません。

関連する問題