ビジネスロジックの委任とカプセル化の境界はどこにありますか?委任すればするほど、貧血になります。ただし、委任は再利用とDRYプリンシパルも促進します。それでは、委任するのに適切なものと、ドメインモデルに残すべきものは何でしょうか?
例として、次の懸念事項を取り上げます。
認証。ドメインオブジェクトは、そのアクセス制御ルール(CanEditプロパティなど)を維持する必要がありますか、それともアクセスの管理のみを行う別のコンポーネント/サービス(IAuthorizationService.CanEdit(object)など)に委任する必要がありますか?それとも、2つの組み合わせにする必要がありますか?おそらく、ドメインオブジェクトには、実際の作業を実行するために内部IAuthorizationServiceに委任するCanEditプロパティがありますか?
検証。上記と同じ議論は検証に関するものです。誰がルールを維持し、誰がルールを評価する責任がありますか?一方では、オブジェクトの状態はそのオブジェクトに属している必要があり、有効性は状態ですが、すべてのドメインオブジェクトのルールを評価するために使用されるコードを書き直したくありません。我々は可能性があり、この場合の継承を使用して...
オブジェクトの作成。ファクトリクラスとファクトリメソッド、インスタンスの「更新」。別のファクトリクラスを使用する場合、作成ロジックを分離してカプセル化できますが、オブジェクトの状態をファクトリに開くことを犠牲にします。これは、ファクトリが使用する内部コンストラクターを公開することでドメインレイヤーが別のアセンブリにある場合に管理できますが、複数の作成パターンがある場合は問題になります。そして、すべてのファクトリーが適切なコンストラクターを呼び出している場合、ファクトリーを持つことのポイントは何ですか?
クラスのファクトリメソッドは、オブジェクトの内部状態を開く問題を排除しますが、静的であるため、別のファクトリクラスの場合のように、ファクトリインターフェイスの注入によって依存関係を解除することはできません。
永続性。ドメインオブジェクトがCanEditを公開し、承認チェックを実行する責任を別の関係者(IAuthorizationService)に委任する場合、同じことを行うドメインオブジェクトにSaveメソッドがないのはなぜでしょうか。これにより、オブジェクトの内部状態を評価して、カプセル化を中断せずに操作を実行できるかどうかを判断できます。もちろん、リポジトリオブジェクトをドメインオブジェクトにインジェクトする必要がありますが、これは少し気になりますが、代わりにドメインイベントを発生させ、ハンドラーが永続化操作を実行できるようにしますか?
これでどこに行くのかわかりますか?
Rockford Lhotkaは、CSLAフレームワークのクラスインチャージルートに進む理由について素晴らしい議論をしており、そのフレームワークには少し歴史があり、ドメインオブジェクトと並行するビジネスオブジェクトの彼のアイデアをさまざまな方法で見ることができます。しかし、良いDDDの理想にもっと忠実になろうとしているので、コラボレーションが過剰になりすぎるのではないかと思っています。
集約ルートのIAuthorizationService、IValidator、IFactory、およびIRepositoryで終わる場合、何が残っていますか?オブジェクトの状態をDraftからPublishedに変更するPublishメソッドを使用して、クラスを非貧血ドメインオブジェクトと見なすのに十分ですか?
あなたの考え?