あなたがソーシャルネットワークを構築すると想像してみてください。他のユーザーを友達として追加できるユーザーがいます。これをDDDでどのようにモデル化しますか?当然のことながら、クラスに友達のリストを単純に含めることはできません。User
友達のループがあると、そのようなユーザーをリポジトリから取得するときに無限の再帰が発生するためです。
保留中、キャンセル、承認、または拒否される可能性のある友達リクエストを追跡する必要がある場合、モデルをどのように変更しますか?
あなたがソーシャルネットワークを構築すると想像してみてください。他のユーザーを友達として追加できるユーザーがいます。これをDDDでどのようにモデル化しますか?当然のことながら、クラスに友達のリストを単純に含めることはできません。User
友達のループがあると、そのようなユーザーをリポジトリから取得するときに無限の再帰が発生するためです。
保留中、キャンセル、承認、または拒否される可能性のある友達リクエストを追跡する必要がある場合、モデルをどのように変更しますか?
うーん...実は、あなたが求めたことをするのはとても簡単で、あなたの状況は標準的なものです。アグリゲートに実際のUser
オブジェクトを格納する必要はありません。の友達であるユーザーのIDをそこに配置するだけです。Friendslist
User
User
これは、Vaugh Vernonによって提案された集約実装のルールの1つです。つまり、IDによって他の集約およびエンティティにリンクします。したがって、ループはなく、IDのリストだけです。
そのような状況では、誰かが誰かの友達になり、一度に2つのアグリゲートを変更する必要があります。1つのトランザクションで変更を即座に発生させることはできないため、これは望ましくない動作になる可能性があります。ただし、この場合、ドメインイベントがあり、フレンドリクエストは簡単にモデル化できます。アグリゲートは、、、またはイベントと相互に通信し、それに応じてFriendshipRequested
状態を変更できます。FriendshipAccepted
FriendshipCancelled
FriendshipDeclined
この場合、ログと通知も無料で受け取ります。
AUser
はのリストを持つことができますFriend
。AFriend
は、UserId、FriendType、GroupIdなどで構成できます。
AUser
はsのリストを持つこともできFriendRequest
ます。AFriendRequest
には、UserId、RequestMessage、RequestStatusなどがあります。
User
、Friend
およびFriendRequest
すべてが同じ集合体の一部である可能性があります。ただし、そうすることで重複が生じる可能性があります。もう1つのオプションは、関係する両方のユーザーに対して1つのFriendRequestを設定し、各ユーザーが送受信されたFriendRequest
IDのリストを持つことです。
DDDでは、デザインはアプリの動作方法と必要な機能に大きく依存するため、これはいくつかのアイデアを提供するためのものです。;-)
それは、一貫性の境界がどこにある必要があるかに大きく依存します。したがって、これはあなたが持っているビジネスルールにも依存します。
Meta-Knightは同じアグリゲートにFriendRequestを持っていますが、私はそれを独自のものとして持ち、イベントを使用してアグリゲート間で通信するため、PersonとそこでのFriendRequestは結果整合性があります。これにより、次のようなことができるようになります。
public class DomainRouter {
public void When(FriendRequestCreated event)
{
//Send command to each Person to record request
}
public void When(FriendRequestAccepted event)
{
//Send command to Person to record request accepted and add friend.
//Send comamnd to Person who accepted to add Friend
}
public void When(FriendRequestDeclined event)
{
//Send command to update Friend request on person.
//Send command to Person who declined to record they have declined?
}
}
したがって、Personに関する情報は、状態の記録にすぎません。FriendRequest Aggregateは、すべてのプロセスが実際に行われる場所です。
DDDで重要なのは、行動について考えることです。FriendRequestは、要求、撤回、承認、および拒否することができます。人は何ができますか?PersonはDDDdである必要がありますか、それとも単純にCRUD+グラフデータベースなどに情報を保存するようにすることができますか?
おそらく、person.requestFriendAcceptance(Person id)に移動できるようにモデル化する必要があります。その場合、ルーターは、FriendRequestを友人に通知することでFriendRequestCreatedイベントを処理するだけです。