web-dev-qa-db-ja.com

ドメインモデルでの検証とデータの永続性

私の(最初の、そして現在の)職場(.NETショップ)は、過剰な 貧血ドメインモデル に悩まされています。適切なドメインモデル。

データの永続性

1つのオプションは、ドメインモデルに永続性自体を実行する方法を提供することです。たとえば、コンストラクターインジェクションを介して IFooRepository をインジェクトし、IoCコンテナーによってそれを解決して、依存関係を作成しないようにすることができます(àla タマネギのアーキテクチャ )。しかし、ドメインモデルを使用するコードがデータを保存するメソッドの呼び出しなどを担当する必要があるかどうか、またはバックグラウンドスレッドのバックグラウンドで暗黙的に実行する必要があるかどうかはわかりません。おそらくこれはドメインモデルの純粋さを壊し、 アクティブレコード パターンの線に沿ったものになります。

私が目にするもう1つのオプションは、ドメインモデルをデータの永続性にまったく関連付けず、代わりに調整面 サービスレイヤー がその側面を担当することです。

ドメインモデルパターンでのデータ永続化のベストプラクティスは何ですか?

検証

適切なドメインモデルで解決する方法がわからないもう1つの問題は、UIにどのように示すかwhy現在のモデルの状態が、 (または少なくともそれに対応する)UI。たとえば、ユーザーがさまざまなフィールドに入力するフォームがあるとします。その入力を検証し、何か問題がある場合は、その特定のフィールドのエラーをメッセージで示します。

ドメインモデルに大幅な複雑さを追加したり、ハックっぽい文字列型の処理(プロパティの名前とメッセージで検証例外をスローするなど)を実行したりせずに、そのレベルの粒度で検証をどのように処理しますか?

5
Jeff B

私は誤解しているかもしれませんが、あなたがドメインモデルを再設計して、貧血に悩まされないようにしようとしていると思います。この問題についての本当にすばらしい本をいくつか挙げます。

  • Martin Fowler-エンタープライズアプリケーションアーキテクチャのパターン
  • Eric Evans:ドメイン駆動設計:ソフトウェアの心臓部における複雑性への取り組み
  • Vaughn Vernon:ドメイン駆動設計の実装

彼らはあなたの目標に関するかなりの数の質問に答える多くのコンテンツを持っています。その1つは次のとおりです。

リッチドメインモデルは、継承、戦略、その他の4つのギャングパターン、および相互接続された小さなオブジェクトの複雑なWebを使用して、データベース設計とは異なる外観にすることができます。リッチドメインモデルは、より複雑なロジックには適していますが、データベースへのマッピングが困難です。

シンプルなドメインモデルではアクティブレコードを使用できますが、リッチドメインモデルではデータマッパーが必要です。ビジネスの動作は多くの変更の影響を受けるため、このレイヤーを簡単に変更、構築、テストできることが重要です。

それはファウラーからの抜粋です。彼はモデルが貧血で膨満しているモデルについても詳しく説明します。私への質問の範囲はかなり大きいようです。だから私はそれを深く掘り下げることができるかどうかわかりません。それらの本はあなたを正しい方向に向けるべきです。また、現在のプロジェクトと実装を測定して、すばやくリファクタリングすることもできます。

比較的基本的な理解から:

[〜#〜] ui [〜#〜]Data Accessを簡単にオーバーレイして、モデルを抽象化できるはずですドメインモデル。しかし、それ以外の場合、モデルは明確でクリーンで簡潔な実装を可能にする必要があります。これは、責任の分離に役立ちます。

すみません、これ以上助けられませんでした。

4
Greg

問題は、UIがデータを取得するために使用しているものと、永続化するためにデータを送信する方法です。サービスレイヤーがなく、UIがドメインクラスと直接連動するため、検証に適した場所を見つけるのに苦労しているとのことですが、恐れています。それは良い方法かもしれませんが、非常に複雑なアプリケーションのようには聞こえず、UIコードで直接永続化作業とクエリを実行できます。 Ayende Rahienや、リポジトリの削除について語っている他の多くの投稿をチェックできます。比較的単純なシナリオでは、ORMは永続性自体からドメインモデルを十分に分離できます。また、現代のORMを純粋にDALと見なすことができるかどうかは問題です。 NHibernateを見てください。単純なテーブルを単純なクラスにマッピングするだけではありません。そして、リポジトリを見ると、GetByThisおよびGetByThatと呼ばれる一連のメソッドが見つかります。これらのメソッドは、ORMに単純なクエリを発行し(もちろん、いずれかを使用している場合)、不要な抽象化のばかげた役割を果たすだけで、 DDDを実行します。

リポジトリを挿入して「作成しない」依存関係に関するコメントについて-制御を無効にしますが、ドメインオブジェクトでリポジトリクラスインスタンスを使用するとすぐに依存関係が生じます。どのようにして到達するかは問題ではありません。したがって、これはすべての悪い選択です。

検証の質問に対しては、検証自体を綿密に調べて、どの検証がドメイン固有であり、何がデータ入力固有であるかを決定することをお勧めします。必須フィールドのようなデータ入力検証は、ドメインモデルによってチェックされるべきではありません。それは単純な仕事であり、UIレイヤーはそれを完全に実行できます。さらに、最新のUIのほとんどは、この検証を非常に簡単に行うことができます。ただし、データ入力規則についてUIに通知する方法を見つける必要があります(以下で説明します)。ドメインモデルは、そのような名前の顧客がすでに存在する場合のように、よりビジネス指向の検証を実行する必要があります。ただし、ドメインクラス内で既存のデータをクエリすることはできないため、ドメインクラス内でこれを行うことはできません。これは、独自の集計の外側にあるものについてはドメインオブジェクトの責任ではないためです。

したがって、DDDジャーニーに対処したい場合は、CQRSの原則を確認することをお勧めします。多くの場合、イベントソーシングにバインドされていますが、これは省略できます。永続化のためにORMやNoSQLを使用して、または使用せずにRDBMSを使用する場合、このシナリオに集中してください。

  • UIのみで使用される入力モデルとビューモデルを作成します。
  • クライアント側の検証のために、データ属性で入力モデルを装飾します。
  • UIからバックエンドにコマンドを送信して、ビジネスの検証と永続化を行います。
  • UIからバックエンドにクエリを送信して、表示するデータを取得します。返されたデータはビューモデルに配置する必要があります。
  • ドメインイベントを使用して、異なる境界コンテキスト間で通信する

アプリケーションサーバーにバックエンドロジックを配置する必要は必ずしもありません(ただし、同じバックエンドで複数のUIを使用できるようにすることが非常に望ましいです)。インメモリイベントを使用して、コマンドやクエリを送信することもできます。

しかし、もう一度、あなたが本当に必要なものを見てください。本がそう言っているからといって、抽象化を拡大しすぎないようにしてください。誰かがこれが良いことだと聞いたからといって、非常に頻繁に抽象化が行われることを覚えておいてください。リポジトリは、システムの永続性を無知にするとORMを変更できると人々が言う典型的な例ですが、実際には誰もそれを行いません。 ORMが変更されると、ほぼ完全な再設計が行われ、リポジトリは他のすべてのコードと同様に適切に廃棄されます。

4
Alexey Zimarev