この質問をしてからほぼ 1 年が経ちましたが、それ以来、私と私のチームは多くのことを学びました。今日、この質問に私が答える方法は次のとおりです。
ドメインは、ビジネスが何であるか、または (実生活で) 何を行っているかを (コードで) 表す必要があります。したがって、ドメイン エンティティは、実際のビジネスで見られるアーティファクトまたはアクターです。それらの現実のアーティファクトと俳優はどのような行動をとりますか? それのすべて。次に、ドメインエンティティはどのような振る舞いをすべきでしょうか? それのすべて。
たとえば、実生活では、マネージャーは新しい従業員を雇うことができます。そのドメインの表現には、「マネージャー」や「新入社員」などのエンティティが含まれている必要があります。マネージャーは俳優です、ここで。
//newEmployee comes from somewhere else... possibly the UI
//someManagerId comes from the logged in user
var manager = _repository.Get<Manager>(someManagerId);
manager.Hire(newEmployee);
したがって、マネージャー エンティティは、現実のビジネスの行動をモデル化/反映します。別の方法は、マネージャ エンティティをアクターとしてスキップし、彼を追い詰めて、面倒な「ドメイン サービス」がすべての作業を実行できるようにすることです...次のように:
//newEmployeeService comes from somewhere else... possibly injected using IOC
newEmployeeService.Create(newEmployee, someManagerId);
貧血ドメインでは、このようなドメイン サービスを使用して従業員を作成または雇用します。機能しますが、表現力がなく、動作がわかりにくいです。誰が何をしますか?マネージャーが新しい従業員を作成する必要があるのはなぜですか?
最初に質問したとき、エンティティにもっと多くの動作を含めたいと思ったのですが、エンティティにサービスを注入しないと (たとえば、コンストラクター注入を使用して) どうすればよいかわかりませんでした。それ以来、私たちはいくつかの新しいトリックを学び、私たちのチームのエンティティは非常に表現力豊かです. 簡単に言えば、私たちがやっていることは次のとおりです。
- 可能であれば、アクター エンティティを使用して、アクションを実行している人または物を表現しようとします。
- アクターには、実行できるアクションを表現するメソッドがあります
- サービスが必要な場合は、それが使用されるメソッドに引数として挿入されます。
- すべてのドメイン エンティティのすべてのメソッドでBlingBagを使用してドメイン イベントを発生させ、拡張性を提供し、エンティティに自己永続化機能を提供します。