現在のデザインにはstudentとgroupの2つのモデルがあります。学生とグループはどちらも集合根です。
生徒はグループ(グループ集約ルートのメソッド)に追加でき、グループの全期間または一部の期間アクティブにすることができますそれ。グループには、「特定のグループに追加されたすべての学生がグループの全期間アクティブであるか、グループの開始日と終了日内にある開始日と終了日が必要です。これらの接続( group.student)は、グループの集合に属する子エンティティ(0 .. *)として保存されます。
ただし、Groupには「コースコード」と呼ばれるプロパティもあります。これは、特定のコードと追加の(この例では無関係な)データを含む値オブジェクトです。
私が苦労している部分。ドメインとシステムのビジネスルールの1つは、学生が特定の日付にコースコードごとにアクティブなグループ接続を1つしか持てないことです。つまり、学生がグループに追加された場合、Group.AddStudent(student、daterange)メソッドは、学生が指定された日付範囲で同じコースコードを持つ別のグループへのアクティブな接続。これは、単一のグループ集計に属さないデータであり、現在、(f.eg)student.groupsでアクティブなグループについて生徒にクエリを実行できないため、生徒にも属していません。双方向の関係を回避するために、このように意図的にモデル化しました。
私が考えたこと
同様の状況に遭遇した他の誰か?どのように解決しましたか?
私は人工的な不変量についての議論を控え、そのような複雑な不変量が存在しなければならない説得力のある理由があると仮定します。また、アクティブ/非アクティブ+コースID +日付範囲の可能な組み合わせを制限することにより、より単純なシステムを考え出すためにルールを再評価する方法は絶対にないと仮定します。 ...
はい。あなたの選択はここで制限されます(そして実際にはすべて同じ方法でさまざまな方法でパッケージ化されています)。オプション1は、Course
とGroup
のコレクションを持つ単一の集合体Student
にすべてをまとめて、Student
はGroup
に入ります。もちろん、これは、これらの接続のいずれか1つを変更しようとするたびに、不必要でコストがかかる可能性のある状態をロードすることを意味します。システムのサイズによっては、単一のアグリゲートの単純さは実現できない場合があります。
オプション2は、システムにロードされるデータの量を目的のユースケースに必要な量に制限するために、適切な状態のスライスをモデル化することです。つまり、ユースケースの実行、データの入力、調整に必要な状態のスライスを明示的にモデル化します。ドメインサービスからクエリを発行する理由はありません。これは、AddStudentToGroup
の使用例では、特定の日付範囲で学生が現在アクティブなすべてのグループとグループが必要であることを知っているためです生徒を追加する予定です。これらのクエリは発行できますfirstしたがって、データ(モデル)のみを調整のためにドメインサービスに渡す必要があります。