Basic Aggregate Question

后端 未结 4 1731
孤独总比滥情好
孤独总比滥情好 2021-01-06 17:57

Is client code allowed to reference entities within an aggregate that is not the root? I have a Story (Root), Team (Entity) and TeamMember

相关标签:
4条回答
  • 2021-01-06 18:36

    My opinion - it should not. Having a reference to an entity that belongs to certain aggregate means that you are able to invoke a method on that entity without full aggregate context and if you allow that, you can never be sure if your entire aggregate is valid and consistent.

    Simple example:

        public class MyAggregateRoot
        {
            protected MyEntity entity;
    
            public void BuildUpAggregate()
            {
                ValidateSomeRule();
                LoadEntityFromDatabase();
            }
    
            public MyEntity MyEntity
            {
                get 
                {
                    VerifySomeOtherRule();
                    return entity; 
                }
            }
        }
    

    As you can see, while building and retrieving MyEntity via aggregate root we have two validation rules checked - if you would allow the client to reference MyEntity directly, the aggregate might change in time between client retrieved the entity and performed an operation on it, so the checks would no longer be valid, but you wouldn't event be aware of this fact. In other words, your aggregate would be inconsistent and potentially invalid.

    In general, in DDD there's a strong rule that states that all access to entities in aggregate should be performed by traversing from the aggregate root - this rule is exactly for the sake of consistency of aggregates.

    That said, what your client can reference is a projection of an entity - a sort of read-only copy that contains only data required for displaying and deciding whether a certain action is available in current context. You can go even further and aggregate the data from a set of entities to a single projection, tune it up a little, so it would be tailored to the requirements of UI. I found this technique quite useful for not allowing my UI to decide how the business domain should be modeled.

    0 讨论(0)
  • 2021-01-06 18:46

    Without knowing how your architecture is supposed to work, it sounds like it should go on Team instead of Story. That's assuming you have a 1 to many from Team to Team Member, and that Team Member is a child of the Team object, not Story.

    0 讨论(0)
  • 2021-01-06 18:56

    I'm not sure about 'root' or 'aggregate' rules but I don't think a Story should know anything about how a Team's membership is managed.

    0 讨论(0)
  • 2021-01-06 18:59

    Team should have "has a" relationship with Team member. where as story and team member are not directly related to each other.

    your class should look like:

    class team
    {
    list<TeamMember> teamMembers;
    void AddTeamMember(TeamMember member){}
    }
    

    another reason why Team must have add team member method, if the method is part of story then you have to explicitly mention in which team you want to add member.

    addteamMember(Team T, TeamMember member);
    

    Root should provide proper methods to access non root elements(first level of nesting). In your case Team should have addTeamMember method and story should have a method (AddMemberToTeam(team t, teammember m)) which calls addTeamMember method of specified team.

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