12

ドメイン駆動設計では、豊富なドメイン モデルを使用することが推奨されます。これは、すべてのドメイン ロジックがドメイン モデルにあり、ドメイン モデルが最高であることを意味します。ドメインモデル自体は理想的には永続性について何も知らないため(データベースなど)、永続性は外部の問題になります。

私は中規模のワンマン プロジェクト (Java の 10 万行以上) で実際にこれを使用してきましたが、多くの利点を発見しています。主に、データベース指向のアプローチに対してこれが提供する柔軟性とリファクタリング性です。ドメイン クラスを追加および削除し、いくつかのボタンを押すだけで、まったく新しいデータベース スキーマと SQL レイヤーが展開されます。

しかし、豊富なドメイン ロジックと、アプリケーションを支える SQL データベースがあるという事実とを調和させるのが難しいという問題に直面することがよくあります。一般に、これは典型的な「1+N クエリの問題」を引き起こします。つまり、N 個のオブジェクトをフェッチし、各オブジェクトに対して重要なメソッドを実行して、クエリを再度トリガーします。これを手動で最適化すると、一定数の SQL クエリでプロセスを実行できます。

私の設計では、システムがこれらの最適化されたバージョンをプラグインできるようにしています。コードを、数十のドメイン固有のクエリ (getActiveUsers など) を含む「クエリ モジュール」に移動することでこれを行います。ナイーブでスケーラブルではない) および SQL ベースの (展開で使用する) 実装。これにより、ホットスポットを最適化できますが、主な欠点が 2 つあります。

  • ドメイン ロジックの一部を実際には属さない場所に効果的に移動し、実際には SQL ステートメントにプッシュすることさえあります。
  • このプロセスでは、クエリ ログを精査してホットスポットの場所を特定する必要があります。その後、コードをリファクタリングし、コードをクエリに落としてレベルの抽象化を減らす必要があります。

ドメイン駆動設計とそのリッチ ドメイン モデルを、すべてのエンティティをメモリ内に保持することができず、データベース バックエンドに限定されるという事実と調和させる、より適切でクリーンな方法はありますか?

4

4 に答える 4

6

この問題を調べるには、少なくとも2つの方法があります。1つは、技術的な「データをよりスマートにロードするために何ができるか」バージョンです。私が知っている唯一の本当に賢いことは、部分的にロードされ、残りがオンデマンドでロードされ、パーツがプリロードされる可能性がある動的コレクションです。これについてJavaZone2008で興味深い話がありました

2番目のアプローチは、私がDDDを使用してきたときの私の焦点でした。DDDの良さをあまり犠牲にすることなく、モデルをより「ロード可能」にする方法を教えてください。長年にわたる私の仮説は、多くのDDDモデルが、すべてのビジネスプロセスおよび各ビジネスプロセスで時間の経過とともに発生するさまざまな状態にわたって、実際にはすべての許容可能なドメイン状態の合計であるドメイン概念をモデル化するというものでした。ドメインモデルがプロセス/状態に関してわずかに正規化されている場合、これらのロードの問題の多くは非常に軽減されると私は信じています。これは通常、「Order」オブジェクトがないことを意味します。これは、オードラーが通常、かなり異なるセマンティクス(ShoppingCartOrder、ShippedOrder、InvoicedOrder、HistoricalOrder)が付加された複数の異なる状態で存在するためです。

しかし、ここには特効薬はありません。

于 2008-12-18T17:15:32.983 に答える
2

私の経験では、これが物事を行う唯一の方法です。永続層を完全に隠蔽または抽象化しようとするシステムを作成する場合、永続層の詳細を使用して物事を最適化する方法はありません。

私は最近この問題に直面しており、永続化レイヤーが最適化を表すインターフェースを実装することを選択できるソリューションに取り組んでいます。私はちょうどそれで遊んでいますが、ListAUsers の例を使用するには、次のようになります...

最初に、ドメイン レベルですべてを行う ListAllUsers メソッドを記述します。しばらくはこれでうまくいきますが、遅くなり始めます。

リッチ ドメイン モデルの使用が遅くなった場合は、"IListActiveUsers" と呼ばれるインターフェイスを作成します (または、おそらくそれ以上のもの)。そして、適切な技術 (おそらく最適化された SQL) を使用して、永続化コードにこのインターフェイスを実装させます。

これで、これらのインターフェイスをチェックし、存在する場合は特定のメソッドを呼び出すレイヤーを作成できます。

これは完璧ではなく、私はこの種のことについて多くの経験を持っていません. しかし、完全に単純な永続化方法を使用している場合でも、すべてのコードが引き続き機能することを確認することが重要であるように私には思えます。これに加えて、最適化を行う必要があります。

于 2008-12-18T17:39:41.030 に答える
0

いいえ、そうではありません。いずれにせよ、私が知っているわけではありません (ただし、DDD の支持者の反対の反応を聞くことに興味があります)。

私自身の経験と、私が一緒に働いている非常に経験豊富なチームの経験では、データベースに支えられたアプリケーションから最適なパフォーマンスが必要な場合、そのアーキテクチャをサービス指向に変換することは避けられません。これについてはこちらに詳しく書いています(この記事では遅延ロードされたプロパティについて説明していますが、ジョブを実行するためにより多くのデータを取得する必要があるクラスのメソッドに適用するポイントを考えることができます)。

現在行っているのと同じように、豊富なドメイン モデルから始めて、パフォーマンス上の理由から必要に応じてそれをサービス指向に変換することができます。パフォーマンス目標を定義し、それを達成している限り、すべてを変革する必要はありません。それはかなりまともな実用的なアプローチだと思います。

于 2008-12-18T16:54:33.633 に答える