DDD and Homogeneous Many-to-Many Relationship

后端 未结 3 1646
梦谈多话
梦谈多话 2021-02-06 16:44

Imagine you build a social network. There are users who can add other users as friends. How do you model this in DDD? Naturally you cannot simply have a list of friends in the <

相关标签:
3条回答
  • 2021-02-06 17:30

    That would very much depend on where you consistency boundaries need to be. Which would also therefore depend on what business rules you have.

    While Meta-Knight has FriendRequest in the same Aggregate I would have it as its own and use events to communicate between the Aggregates therefore making a Person and there FriendRequests eventually consistent. This would allow you to do something like.

    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?
        }
    }
    

    The information on Person would therefore just be a record of state. The FriendRequest Aggregate would be where all the process actually happens.

    What is important in DDD is to think about behavour. A FriendRequest can be Requested, Withdrawn, Accepted and Declined. What can a Person do? Does a Person need to be DDDd or could you make it nice and simply CRUD + store info into graph database etc.

    Maybe you want to model it that in a way where you can go person.requestFriendAcceptance(Person id) in which case the router would probably just handle the FriendRequestCreated event by notifying the friend of a FriendRequest.

    0 讨论(0)
  • 2021-02-06 17:41

    A User could have a list of Friends. A Friend could consist of a UserId, FriendType, GroupId, etc.

    A User could also have a list of FriendRequests. A FriendRequest could have a UserId, RequestMessage, RequestStatus etc.

    User, Friend and FriendRequest could all be part of the same Aggregate. But there could be some duplication by doing so. Another option would be to have one FriendRequest for both users involved, and each user would have a list of received and sent FriendRequest IDs.

    This is just to give you some ideas because in DDD, your design will depend highly about how your app will work, and which features are needed. ;-)

    0 讨论(0)
  • 2021-02-06 17:42

    hmm... Actually it's quite easy to do what you've asked, and your situation is a standard one. You don't have to store actual User object in Friendslist of your User aggregate, just put there IDs of users who are friends for the User.

    This is one of the rules of aggregate implementation proposed by Vaugh Vernon: link to other aggregate and entities by their ID. So no loops, just list of IDs.

    In that situation then somebody become a friend to somebody you have to change two aggregates at one time. It can be undesirable behavior because change can't occur instantly in one transaction. But for this case you have Domain Events and friend requests can be easily modeled: your aggregates can communicate with each other with FriendshipRequested, FriendshipAccepted, FriendshipCancelled or FriendshipDeclined events and change their state correspondingly.

    In this case you also receive logs and notifications for free.

    0 讨论(0)
提交回复
热议问题