私の会社はWebアプリケーションをゼロから書き直しています。これは、金融業界で複雑なドメインを持つ大規模なエンタープライズレベルのアプリケーションです。
永続化のためにORM(エンティティフレームワーク)を使用しています。
本質的に、アプリケーションの半分はユーザーから生データを収集して保存することに集中しており、実際のドメインロジックのほとんどを含むアプリケーションの残りの半分はその生データを使用して、元のデータとは大きく異なるドメイン画像を作成します生の入力、およびそれを計算エンジンに渡し、計算を実行し、結果を吐き出し、ユーザーに表示します。
レイヤーを使用したDDDアプローチでは、CRUD操作がドメインレイヤーを通過するように見えます。しかし、少なくとも私たちの場合、これは意味をなさないようです。
たとえば、ユーザーが編集画面に移動して投資口座を変更した場合、画面のフィールドはデータベースに保存されているフィールドそのものであり、後で計算に使用されるドメイン表現ではありません。では、編集画面でデータベース表現(生の入力)が必要なときに、なぜ投資口座のドメイン表現をロードするのでしょうか。
ユーザーが投資アカウント画面で[完了]をクリックし、POST=がコントローラーに対して実行されると、コントローラーは保存する必要のある投資アカウントのデータベース表現をほぼ正確に保持します。 。しかし、何らかの理由で、コントローラーのモデルをデータベースモデル(エンティティフレームワークモデル)に直接マッピングするのではなく、ドメイン表現をロードして変更を行うことになっていますか?
つまり、本質的には、データモデルをドメインモデルにマッピングします。これにより、永続化するためにデータモデルにマッピングし直すことができます。それはどういう意味ですか?
フォームの投稿をEFオブジェクトに直接マッピングするアカウント作成ページを実装し、それをデータベースに保存するとします。
さらに、データベースには、完全に誤ったデータが入力されるのを防ぐさまざまな制限があると仮定しましょう。アカウントには常に顧客などがあります.
すべてがうまくいくようです。しかし、ビジネスは新しいルールを作ります。
ここで、このロジックをどこかに配置する必要があり、それを配置するドメインオブジェクトがありません。
DDDは、常にこの種のルールがあることを前提としています。アカウントの作成には、さまざまなチェック、監査ログなどが必要です。「データベースに行を書き込む」だけではありません。
追加のロジックを含む永続性またはMVCコントローラーがないと想定して、ドメインを計画します。要件のallをキャプチャし、それらがすべてドメインモデルにあることを確認してください。
それはどういう意味ですか?
短い答え:それはしません。
より長い答え:ドメインモデルを開発するためのヘビーウェイトパターンは、ソリューションのデータベースだけの部分には適用されません。
ウディダーハンは興味深い観察をしました これを明確にするのに役立つかもしれません
Dahanは、サービスにはある種の機能とデータの両方が必要であると考えています。データがない場合、それは単なる関数です。データに対してCRUD操作を実行するだけの場合は、データベースです。
結局のところ、ドメインモデルのポイントは、データに対するすべての更新が現在のビジネスの不変を維持することを保証することです。または、言い換えると、ドメインモデルは、がレコードのシステムとして機能するデータベースが正しいことを確認する責任があります。
CRUDシステムを扱う場合、通常はデータの記録システムではありません。 実世界は記録の本であり、あなたのデータベースは実世界のローカルにキャッシュされた表現です。
たとえば、メールアドレスや政府発行の識別番号など、ユーザープロフィールに表示されるほとんどの情報には、ビジネスの外部に存在する真実の情報源があります-それは誰か他人のアプリではなく、メールアドレスの割り当てと取り消しを行うメール管理者。 SSNを割り当てるのは政府であり、アプリではありません。
そのため、通常、外部から送信されるデータに対してドメイン検証を実行することはありません。データが適切に形成され、適切に作成されていることを確認するためのチェックが行われている可能性があります sanitized ;しかし、それはあなたのデータではありません-あなたのドメインモデルは拒否権を取得しません。
レイヤーを使用したDDDアプローチでは、CRUD操作がドメインレイヤーを通過するように見えます。しかし、少なくとも私たちの場合、これは意味をなさないようです。
そうですデータベースは記録簿ですの場合です。
ただし、多くのレガシーコードに取り組んでいますが、ドメイン内にあるものとドメイン外にあるものを識別するためによくある間違いを観察しました。
データモデルの周りにビジネスロジックがない場合にのみ、アプリケーションをCRUDと見なすことができます。この(まれな)場合でも、データモデルはドメインモデルではありません。これは、ビジネスロジックが関与していないため、それを管理するための抽象化が必要ないことを意味し、ドメインモデルがありません。
ドメインモデルを使用して、ドメイン内に属するデータを管理します。ドメイン外のデータはすでに別の場所で管理されています-コピーをキャッシュしているだけです。
Greg Youngは warehouse systems を、記録簿がどこか(つまり、倉庫の床)にあるソリューションの主な例として使用しています。彼が説明する実装は、あなたの実装とよく似ています。ウェアハウスから受信したメッセージをキャプチャする1つの論理データベースと、それらのメッセージの分析から導き出された結論をキャッシュする別の論理データベースです。
では、ここに2つの境界コンテキストがあるのでしょうか?
investment account
のモデルがそれぞれ異なる
多分。他の荷物と一緒に何が付属するのかはっきりしないので、境界付きのコンテキストとしてタグ付けすることには消極的です。コンテキストが2つある可能性があります。ユビキタス言語にわずかな違いがある1つのコンテキストである可能性があります。
可能なリトマステスト:このスペクトルをカバーするために2人のドメインエキスパート、またはコンポーネントについてさまざまな方法で話す1人のドメインエキスパートが何人必要ですか。基本的には、コンウェイの法則を逆算することで、いくつの境界コンテキストがあるかを推測できる場合があります。
境界のあるコンテキストをサービスに合わせると考えると、より簡単になる可能性があります。これらの2つの機能を個別にデプロイできる必要がありますか?はい、2つの境界のあるコンテキストを提案しています。しかし、それらの同期を維持する必要がある場合は、おそらく1つだけです。
あなたのドメインでは、データベースが存在することさえ知る必要はありません。
ドメインはビジネスルールに関するものです。データベースを作った会社が廃業したときに生き残る必要があるもの。つまり、会社を存続させたい場合です。これらのルールが、データの永続化方法を変更したことを気にしない場合、それは本当に素晴らしいことです。
データベースの詳細が存在し、対処する必要があります。彼らは別の場所に住むべきです。境界を越えてそれらを置きます。その境界を越えて通信する方法、または境界ではない方法を慎重に制御します。
ボブおじさんはあなたのデータを何に入れるかについてこれを言っています:
通常、境界を越えるデータは単純なデータ構造です。必要に応じて、基本的な構造体または単純なデータ転送オブジェクトを使用できます。または、データを関数呼び出しの引数にすることもできます。または、ハッシュマップにパックしたり、オブジェクトに構築したりできます。
重要なことは、分離された単純なデータ構造が境界を越えて渡されることです。エンティティやデータベースの行をだまして渡したくありません。データ構造に、依存関係ルールに違反するような依存関係を持たせたくありません。
[…]境界を越えてデータを渡す場合、常に内側の円に最も便利な形式になります。
彼はまた、外側のレイヤーが内側のレイヤーへのプラグインであるべきで、内側のレイヤーが外側のレイヤーが存在することさえ知らないようにする方法も説明しています。
そのようなものに従うと、入力検証ルール、何らかの方法で入力を永続化する必要があるルール、計算を実行するルール、それらの結果を出力に送信するルールを心配できるデータベースを無視するのに最適な場所があります。この種のコードを読む方が実際には簡単です。
それがそうであるか、あなたがあなたのドメインが本当にデータベースを操作するためだけのものであると決めるかです。その場合、ドメイン言語はSQLです。それほど問題ない場合でも、ビジネスルールの実装が永続性の変化に耐えることを期待しないでください。それらを完全に書き換える必要があるでしょう。
DDD理論の適用:
そのドメインには2つの境界コンテキストがあります。
各境界付きコンテキストは、異なるアーキテクチャ設計を持つことができます。
例:
クライアント投資アカウントはエンティティ(多分集合体、ドメインによって異なる)であり、データの永続性はエンティティのリポジトリ(RDBまたはOOデータベース)のような他のタイプのDB)を介して作成されます。
CRUD操作に対するDDDアプローチはありません。オブジェクトのデータに関連付けられたDBフィールドを持つことは、設計原則に違反します。