リッチドメインモデルと貧血ドメインモデルの議論では、インターネットは哲学的なアドバイスに満ちていますが、権威のある例は不足しています。この質問の目的は、適切なドメイン駆動設計モデルの決定的なガイドラインと具体例を見つけることです。(理想的にはC#で。)
実際の例では、このDDDの実装は間違っているようです。
以下のWorkItemドメインモデルは、Entity Frameworkがコードファーストデータベースに使用するプロパティバッグに他なりません。ファウラーごとに、それは貧血です。
WorkItemService層は、明らかにドメインサービスの一般的な誤解です。WorkItemのすべての動作/ビジネスロジックが含まれています。イェメリャノフなどによると、手続き型です。(ページ6)
以下が間違っている場合、どうすれば正しくできますか?AddStatusUpdateまたはCheckoutなど
の動作はWorkItemクラスに属している必要がありますか?
WorkItemモデルにはどのような依存関係が必要ですか?
public class WorkItemService : IWorkItemService {
private IUnitOfWorkFactory _unitOfWorkFactory;
//using Unity for dependency injection
public WorkItemService(IUnitOfWorkFactory unitOfWorkFactory) {
_unitOfWorkFactory = unitOfWorkFactory;
}
public void AddStatusUpdate(int workItemId, int statusId) {
using (var unitOfWork = _unitOfWorkFactory.GetUnitOfWork<IWorkItemUnitOfWork>()) {
var workItemRepo = unitOfWork.WorkItemRepository;
var workItemStatusRepo = unitOfWork.WorkItemStatusRepository;
var workItem = workItemRepo.Read(wi => wi.Id == workItemId).FirstOrDefault();
if (workItem == null)
throw new ArgumentException(string.Format(@"The provided WorkItem Id '{0}' is not recognized", workItemId), "workItemId");
var status = workItemStatusRepo.Read(s => s.Id == statusId).FirstOrDefault();
if (status == null)
throw new ArgumentException(string.Format(@"The provided Status Id '{0}' is not recognized", statusId), "statusId");
workItem.StatusHistory.Add(status);
workItemRepo.Update(workItem);
unitOfWork.Save();
}
}
}
(この例は読みやすくするために単純化されています。コードは紛らわしい試みです。混乱した試みですが、ドメインの動作は次のとおりです。新しいステータスをアーカイブ履歴に追加してステータスを更新します。 CRUDで処理できます。)
更新
@AlexeyZimarevはジミーボガードによるC#の主題に関する完璧なビデオであるベストアンサーを提供しましたが、リンク以外の情報を十分に提供しなかったため、以下のコメントに移動したようです。以下の回答でビデオを要約したメモの大まかなドラフトがあります。修正については、回答に自由にコメントしてください。ビデオは1時間ですが、見る価値があります。
更新-2年後
DDDの成熟期の兆候だと思います。2年間勉強した後でも、「正しい方法」を知っているとは約束できません。ユビキタス言語、集約されたルート、および動作駆動設計へのアプローチは、DDDの業界への貴重な貢献です。永続性の無知とイベントソーシングは混乱を引き起こします。そのような哲学はそれを広く採用することを妨げていると思います。しかし、私が学んだことでこのコードをもう一度やり直さなければならないとしたら、次のように見えると思います。
有効なドメインモデルのベストプラクティスコードを提供するこの(非常にアクティブな)投稿への回答を引き続き歓迎します。
"I don't want to duplicate all my entities into DTOs simply because I don't need it and it violates DRY, and I also don't want my client application to take a dependency on EntityFramework.dll"
。Entity Frameworkの専門用語で「エンティティは、」「ドメインモデル」のような「実体」と同じではありません