Spectacular material to move ideas with a spectacular use case! In fact, I came with a problem in mind, and I solved several others that I had pending. Just to add, there is a little tip (which I think is in Eric's book) and that is: if I delete an Aggregate Root, the elements contained by the Aggregate Root should also be deleted. This helps us discover "whole and its parts" relationships. Through this principle we can ask ourselves: does it make sense to have this entity decoupled from its "root"? Thank you! I enjoyed it a lot.
Nice. So, an aggregate should reference to other aggregate by ID, is that right? And, do we need to add navigation properties for fetching data? Wait for your next video of this topic.
I think that would definitely be a possibility. My idea was that project members should actually have a thread of continuity as roles might change and we want to keep track of different state changes. And that's the scenario for entities. But, for instance, the Customer in the demo is a value object. Aggregates can and should contain both.
Hi!, i found your content is really useful. I want to know though on how to deal with this case: In the Project aggregate root, what if the project members could be a very large members? let's say it could be 10,000 or even 100,000 members in a project. Do we really load the whole project members in the aggregate root? or do we use something like pagination? i feel like we need to do the pagination solution, but i don't know how to implement that in DDD world. meanwhile if we load like 100.000 project members, there could be a memory issue though.
Thanks for the tutorial ! I'm new to DDD and the first thing that pops to me is what should we do in case project has a lot of members. It doesn't seem practical to load them each time into memory while manipulating the project. How should we tackle this ?
Thank you very much for your comment. I'm not really sure how your question fits into the DDD perspective, as this is a challenge for all other types of architecture. To put it into a DDD perspective and based on the experience I had so far in this field I'd say that if you need to load a lot objects, then there's probably something wrong with the overall architecture and design of the application. If I would have a project with 1000+ project members, then I'd probably need to re-model everything. DDD helps you a lot in this regard, starting from signaling out bounded contexts, then keeping aggregates simple (remember the video, an aggregate should only contain objects that are bound together by some very specific business requirements). Adhering to these principles usually leads to pretty small consistency boundaries in which things should be manageable.
Great video. I have one question actually - how you co-relate ProjectMember with Employee class? Maybe I'm missing something but it seems that ProjectMember is a Employee in a certain role. As the rule of thumb is to keep aggregates small - a reasonable decision is to not load all employees into aggregate. You've introduced concept of ProjectMember - do you load all project members into aggregate? What is hundreds of people can join project? Should there join logic be extracted into Domain Service and there check if there are free spots and if Employee is not a member already?
Thanks for this! It's very informative. I'm just wondering how you would handle it if the project member changes his/her FullName. Wouldn't you go back to the original problem?
Well, that's a good question and will be answered in a video. There's also the concept of domain events and side effects and how to use domain events to handle side effects.
Thank for your video. It is very usefull. Let say you have an application with authentication, and users can have different roles. Who is responsible for a method into the aggregate that can have different behaviour according to the role ? And how to get the role of the current user into the aggregate ?
The answer to this is not simple because it really depends on each application requirements. What I have found out in refactoring a lot of production apps towards DDD is that usually the idea of roles is actually not a business rule. That's an application rule and therefore it should be handled at the application level. There are however also scenarios where type of roles would play a big part of the business rules. In these scenario I often found out that the roles that are really needed for the business rules don't usually correspond to the roles we define in our auth systems. For instance, in auth systems we might have a role Admin. In DDD we'd probably have an aggregate called "Administrator". Let me give you a concrete example. I was working on an application that handled approvals for payments in a company. There were different roles involved there. For instance, only a finance user could give the final approval. In the app, everything was a "User". So everything was cumbersome. Talking to the customer while trying to get the ubiquitous language they used, I found out that they were referring to the users in different terms: lawyer, auditor and so on. And it turned on that the auditor was the one approving requests. Therefore, Auditor became part of my domain. Then we had a domain service (see latest video:)) for payment approvals where we provided a paymentRequest and an auditor, and the service enforced all cross-aggregate business rules. The major challenge with DDD is that people try to "do DDD" using a very old mindset. On of these mindsets is that we have a "User" and then we have a bunch of roles. However, if you listen to the ubiquitous language, you'll soon find out that there no such thing as "user". Depending on the domain of the app you might have: ContentCreator, ContentApprover, Accountant, FactoryWorker, Developer and so on. If you're doing DDD for good, you'll probably never have a class "User". Hope this helps.
Thanks for the video! How do we ensure data consistency between the ProjectMember and Employee tables? For example, when an Employee quits, how does that is reflected in the ProjectMember entity? I guess it has something to do with the Domain Events...
How would I do a query that gives me all the projects a employee(user?) has been in? Do we simply add the relation just like in rule 3 to the ProjectMember?
what if you have huge data like 100000000comments in Post object. I don't think you can init a domain object with that much... looks useless to me when dealing with large chuncks of data. Thoughts?
I think that's a problem no matter if you use DDD or not. And the answer to it is sime: you don't load all data at the same time. You introduce paging or fltering based on other data poits that are important for your domain. If you take a look at literally all planet scale apps out there, you'll see that all of them use this approach
Thanks for the video, so clear and instructive. But i have a some complicate situation where i cannot apply the principle of state changing only through aggregate root. Well, suppose i have an entity defined as a shared "business" kernel (ContactInfo, Blob, ...), and witch i use as member of aggregate roots for multiple domains in multiple Microservices. This entity is defined in a separate class library projet (referenced into my domain project). Im forced to define setters inside this shared entity as public. Any alternative ? 🤨Thx
I think there is a common misconception here. Value object can encapsulate their own behavior (methods). Think about the DateTime struct. it has a lot of behavior that's strictly related to a date and time. However, when it comes to an aggregate, the root is the one who should know when certain behavior from the value object should be used or not. I'm not sure I fully understand the challenge.