Looking forward for next chapter. Trying to re-arrange models in my project using your tips from another video about Aggregate Roots, but still finding it's complex, especially when you need to befriend custom aggregates with EF tracker.
I have learnt so much from you, and this, yet again is no exception. I was struggling with this when I first watched his videos but I couldn't vocalise it as well as you have here. I think most of your videos boil down to 2 concepts (with the rest being nuance), coupling and behaviour. I have even gone one step further and created a "code generator", don't judge, that builds code stubs and scaffold using behaviours to ensure the team doesn't fall back into the structure traps. So far it proving VERY useful.
Event Storming helps with identifying events, and behaviours happening in the problem domain. From there you can form the domain boundaries and then aggregates. It is an iterative process and does not come from a first insight. Keep discussing the domain concepts with the business eventually it will become obvious what is what. If you have any workflows, state machines, they are usually about the aggregates.
Great video, thank you Derek :) Modeling is probably one of the most `glanced over` parts of software design and this video provides a great way to think about it.
Plan on expanding this as mentioned with some future videos to give some more insights on how defining the capabilities influences the underlying data and how it's organized.
Please 🙏 do it. Your approach is completely pragmatic. Behaviour is the 'Boss', I could of late able to extract huge a amount of positives out of targeting behaviour than the internals. I was given a huge module at work to rewrite, and I can tell you that I have done it successfully only by aligning my units right ( driving my tests using outside-in )
... and on top of that, if you follow the code in the mentioned example, those GUIDs won't match when creating the Entity and during persistence, can't wait for the follow up vid, modelling is hard for sure. thanks for sharing
I’ve always struggled with aggregate boundaries, the original example referenced helped me a lot, so I’m really looking forward to your behaviour driven approach to define the boundaries with reduced coupling which I have also struggled with!
Very curious to see your approach in Amichai's scenario. I completely understand your focus on behavior instead of data structure, but feel myself more lost on implentation. Defining data structures like Amichai drives you to a straightforward implementation, so looking forward your next video to comprenhend how you define your scenario.
The question to ask is how did you arrive to where you are? Workflows and processes are what drive business. If you're have an object model hierarchy (normalized database schema really), the workflows and processes live in your end users heads, and they execute those on top of your system. Your system doesn't know about them. You'll end up with primarily a CRUD driven system. This is tricky because sometimes you can try and force behaviors where they just don't exist. Example is CreateMenu, AddMenuItem. Is that bad? Depends on what a "Menu" means in your system. "CreateDinner", "UpdateDinner" when your a dinner hosting platform smells off. You're hosting a dinner, making reservations, etc. What's the value in focusing on behaviors (where appropriate)? If you're capturing intent you can then open up the doors to exposing what's happened in your system (events). This leads to the rabbit hole of EDA.
@@CodeOpinion Totally agree with you. Years of experience in CRUD driven systems have taught me the difficulties of adding new functionalities as the system grows. Coincidence or not, both Amichai and you uploaded a new video just after my comment. Thanks a lot for your insights
This is a great video Derek. The issue I unfortunately run into in the corporate world. Since I'm not the architect I never get to implement these patterns and am told 'thats not your job as a dev leave the decision making to the architect'.
Yikes. IMO everyone on a small team can be involved in the design and architecture. That doesn't mean decision making but at least being apart of the understanding of why and all the trade-offs being made.
Devs are in short supply, if you are a good dev just leave. No need to put up with that because there are companies which will respect your role as a dev. But also be cautious when trying new patterns that you dont have experience with because they often look good and easy in youtube videos but then become a nightmare in practice.
Will be interesting to watch your next video. So far, the concept of an aggregate has been helpful to me, especially in the context of the persistence layer. I have created aggregates to determine which subtree of my domain model should be loaded together into a persistence context, modified and saved again. So it's a very transactional view. I understand your approach to pay more attention to the behaviour of a system, but in the end, the resulting transactions must somehow fit the relation model of the ORM.
Having worked with enterprise software for a few decades, at the end of the day - in that world - what everyone cares about is the data. The software on top might change, the UI might change, the flow of data between systems change. But the data is the important thingy. You want to be able to write it somewhere, and retrieve it at some time in the future. I think we developers have a bit too much emphasis on the software, because that's what dear to us. But it isn't really that important. Nobody really cares how you do things, as long as your software solves the user's problems, is fast, secure, without bugs, and you can add features quickly.
Agree'd, however the data you capture is dependent on what users are trying to accomplish, even if it's CRUD. There's workflow and processes in their heads even when using CRUD or excel. The data doesn't come from thin air randomly for no reason. That's my point. You don't have to capture intent everywhere, some places can purely be CRUD. And in those places.. use CRUD. In places where theres a lot of complexity in your software, you need to understand the workflow because the data behind that, as you mentioned, is important.
@@CodeOpinion - yes, I always ask what data is to be captured, and why. Asking people to input data for the fun of it is never a good idea. At the end if the day the important data will be used for something else somewhere.
Would really help to have that next video as it is a bit hard to digest seeing only the wrong way to create a domain model. I can definitely see the model looks awkward right from the start, but still trying to wrap my head around it, because I don't know the full context of the application. My thoughts are though, why would a Menu have behaviors? A menu should be decoupled from whatever is using it, correct?
I would say that the "behavior" is tightly dependant on a business needs, process, rules and boundaries which this "behavior" is supposed to implement, that is why it is very important to understand the business area, i.e. the context. Without deep understading if all business aspects most of the "behaviors" became simple transaction scripts.
Very interested to see your approach to the task. It'd be pretty cool if all the prominent UA-camrs were to tackle the same domain problem. Everyone could learn new approaches and strengths and weaknesses of the designs clearly.
If we're talking about DDD, the problem is with most of the books or resources, that they are too abstract. That is mostly from what I've seen. DDD is hard entry barrier for not only beginners but also more senior developers since books don't provide many in-code examples. Recently, I have been reading a DDD good book by Vladik Khononov, and that one breaks that tendency a bit, which I find personally great.
I've mentioned this a bunch, but for anyone reading again, the issue is providing a context with enough domain complexity to warrant it. Nobody is going to sit through hours of explanation of a complex domain. You have to be abstract enough and the reader/viewer has to hopefully fill in the blanks (correctly) about what "complexity" actually is. Unfortunately, that doesn't seem to happen and patterns/practices are used when it's not justified.
I should have rather used “concrete” than in-code, in the afterthought. But, Stack overflow is filled with basic questions on DDD and not even the complex bits. One of the common complains I hear related to DDD is that “no one knows how to implement this right” which is recurring. For me personally, if I had to start learning it anew from scratch, it would help to sit through an elaborate example of complex domain in form of a workshop or something alike, since it can alleviate most, if not all the questions in a single session.
The problem starts with jumping straight to aggregates before you've worked with the business to understand the actions and events of your system. You can't understand your service boundaries, much less your aggregates, until you have worked out the process and events with the business.
Amichai Mantinband's videos are really focused on defining data structures and not primarily modeling entities with their behavior. Entity here is just a fancy word for an instance of a data class. Why even mention the Id:s? They are an implementation detail and not necessarily part of the model. I know how easy it is as a programmer to jump on implementing something. But the point of DDD is to figure out what to build - and not structuring your code.
Understanding the domain and modeling that in code as relatable as possible. There will always be technicalities in code but more often then not theres not a single model or a single representation that servers all purposes. This wasn't a review so much of that video as using it as inspiration for my own of what I wanted to illustrate.
@@CodeOpinion Sure. I know that. And these were just my immediate thoughts when you mentioned it. I do however think that context is important while modeling. And to keep it balanced. Your model is a representation and don’t let the technical details distract you. Which often happens in these examples.
@@marna_li So many toy examples leave out technical details to the point of uselessness. I'd rather see too many details than not enough. Furthermore, leaving off details can make the design appear cleaner than it actually is once you go to implement it. For example, one thing I really do like about this channel is he mentions technical concerns like consistency, whereas so many examples just completely ignore it.
@@bobbycrosby9765 I meant that it focus a lot on how it is being implemented rather than how to approach software development in terms of organising and finding a structure that lets the project and codebase evolve. Yeah. Consistency and such is seldom taked about in other channels. It is quickly skipped over and taken for granted. I guess the point is that other samples are not complex enough. But to understand stuff, perhaps more in-depth technical examples are great. Not just as part of some mega reference project.
Funny I don’t know anything about DDD but I wanted to comment that you should start the design from the actions you want to be able to get or do as a user until he said it himself.
This seems like it's going to create tons of technical debt and will pull on the proverbial string when the behaviors/actions inevitably need to be modified or are simply deleted because a process is no longer needed.
Is a "User" really an entity? I often question things like this because the concept of a "user" is not actually part of the problem domain, but something that came into existence when we are trying to automate the solution. Just a curiosity, great video as usual!
If you watch enough of my videos, you'll notice an underlying thread (continuation). They all relatively relate to each other in the grand scheme of things.
Good video. Again. Jeez, Derek, the high quality of your content is getting oh-so-monotonous.... 😀 Yup...understanding the transactional / consistency boundaries in your system is driven by understanding the behaviours within your system that require consistency to be maintained. And then starting to think about Aggregate Roots. On the other hand, beginning with your domain objects and data structures rather than behaviours will have you scratching your head pretty quickly in anything other than the most simple systems. At some point a new behaviour will come along that will have you jumping through hoops with your domain model. And probably refactoring regularly as you discover the cascade of unintended complexities that you may have introduced by starting from the wrong place. And then comes the the *next* behaviour that has you doing the same thing all over again (but this time with possibly even more complexity and hoops to jump though) until you realise that starting with behaviours first was the best way to go right from the start. I look forward to your follow-on video!
Thanks. A lot of what I was describing is one step farther from "entity services", which is why things become highly coupled. If you have the concept of entity that exists solely exists in one aggregate, you then need to reference that aggregate because it contains all the data for everything "related" to it.
Looking forward for next chapter. Trying to re-arrange models in my project using your tips from another video about Aggregate Roots, but still finding it's complex, especially when you need to befriend custom aggregates with EF tracker.
Danke!
I had to pause the video at 0:50 to say how much I love these diagrams. This is a wonder representation of how these things are structured.
I have learnt so much from you, and this, yet again is no exception. I was struggling with this when I first watched his videos but I couldn't vocalise it as well as you have here. I think most of your videos boil down to 2 concepts (with the rest being nuance), coupling and behaviour. I have even gone one step further and created a "code generator", don't judge, that builds code stubs and scaffold using behaviours to ensure the team doesn't fall back into the structure traps. So far it proving VERY useful.
Event Storming helps with identifying events, and behaviours happening in the problem domain. From there you can form the domain boundaries and then aggregates. It is an iterative process and does not come from a first insight. Keep discussing the domain concepts with the business eventually it will become obvious what is what. If you have any workflows, state machines, they are usually about the aggregates.
I'm really excited to see your next chapter, and if it's possible, could you consider creating another series about ERP systems, eh?
Great video, thank you Derek :) Modeling is probably one of the most `glanced over` parts of software design and this video provides a great way to think about it.
Plan on expanding this as mentioned with some future videos to give some more insights on how defining the capabilities influences the underlying data and how it's organized.
@@CodeOpinion Every thought about making a whole course where you show how you would solve a non-trivial real-world problem?
Please 🙏 do it. Your approach is completely pragmatic. Behaviour is the 'Boss', I could of late able to extract huge a amount of positives out of targeting behaviour than the internals. I was given a huge module at work to rewrite, and I can tell you that I have done it successfully only by aligning my units right ( driving my tests using outside-in )
... and on top of that, if you follow the code in the mentioned example, those GUIDs won't match when creating the Entity and during persistence, can't wait for the follow up vid, modelling is hard for sure. thanks for sharing
Ah! Juat saw this again. As an old geezer, I was taught to do OOD by identifying entities. I needed to hear this. Thanks!!!
I’ve always struggled with aggregate boundaries, the original example referenced helped me a lot, so I’m really looking forward to your behaviour driven approach to define the boundaries with reduced coupling which I have also struggled with!
Very curious to see your approach in Amichai's scenario. I completely understand your focus on behavior instead of data structure, but feel myself more lost on implentation. Defining data structures like Amichai drives you to a straightforward implementation, so looking forward your next video to comprenhend how you define your scenario.
The question to ask is how did you arrive to where you are? Workflows and processes are what drive business. If you're have an object model hierarchy (normalized database schema really), the workflows and processes live in your end users heads, and they execute those on top of your system. Your system doesn't know about them. You'll end up with primarily a CRUD driven system. This is tricky because sometimes you can try and force behaviors where they just don't exist. Example is CreateMenu, AddMenuItem. Is that bad? Depends on what a "Menu" means in your system. "CreateDinner", "UpdateDinner" when your a dinner hosting platform smells off. You're hosting a dinner, making reservations, etc. What's the value in focusing on behaviors (where appropriate)? If you're capturing intent you can then open up the doors to exposing what's happened in your system (events). This leads to the rabbit hole of EDA.
@@CodeOpinion Totally agree with you. Years of experience in CRUD driven systems have taught me the difficulties of adding new functionalities as the system grows. Coincidence or not, both Amichai and you uploaded a new video just after my comment. Thanks a lot for your insights
Awesome!
I really like the pragmatic way of your designs.
Thank you! Cheers!
This is a great video Derek. The issue I unfortunately run into in the corporate world. Since I'm not the architect I never get to implement these patterns and am told 'thats not your job as a dev leave the decision making to the architect'.
Yikes. IMO everyone on a small team can be involved in the design and architecture. That doesn't mean decision making but at least being apart of the understanding of why and all the trade-offs being made.
Devs are in short supply, if you are a good dev just leave. No need to put up with that because there are companies which will respect your role as a dev. But also be cautious when trying new patterns that you dont have experience with because they often look good and easy in youtube videos but then become a nightmare in practice.
Will be interesting to watch your next video. So far, the concept of an aggregate has been helpful to me, especially in the context of the persistence layer. I have created aggregates to determine which subtree of my domain model should be loaded together into a persistence context, modified and saved again. So it's a very transactional view. I understand your approach to pay more attention to the behaviour of a system, but in the end, the resulting transactions must somehow fit the relation model of the ORM.
Having worked with enterprise software for a few decades, at the end of the day - in that world - what everyone cares about is the data.
The software on top might change, the UI might change, the flow of data between systems change. But the data is the important thingy.
You want to be able to write it somewhere, and retrieve it at some time in the future.
I think we developers have a bit too much emphasis on the software, because that's what dear to us. But it isn't really that important.
Nobody really cares how you do things, as long as your software solves the user's problems, is fast, secure, without bugs, and you can add features quickly.
Agree'd, however the data you capture is dependent on what users are trying to accomplish, even if it's CRUD. There's workflow and processes in their heads even when using CRUD or excel. The data doesn't come from thin air randomly for no reason. That's my point. You don't have to capture intent everywhere, some places can purely be CRUD. And in those places.. use CRUD. In places where theres a lot of complexity in your software, you need to understand the workflow because the data behind that, as you mentioned, is important.
@@CodeOpinion - yes, I always ask what data is to be captured, and why. Asking people to input data for the fun of it is never a good idea. At the end if the day the important data will be used for something else somewhere.
Would really help to have that next video as it is a bit hard to digest seeing only the wrong way to create a domain model. I can definitely see the model looks awkward right from the start, but still trying to wrap my head around it, because I don't know the full context of the application. My thoughts are though, why would a Menu have behaviors? A menu should be decoupled from whatever is using it, correct?
How do I make DDD simple for the junior devs on my team? The terminology is difficult for me to grok let alone someone entirely new to the field.
I would say that the "behavior" is tightly dependant on a business needs, process, rules and boundaries which this "behavior" is supposed to implement, that is why it is very important to understand the business area, i.e. the context. Without deep understading if all business aspects most of the "behaviors" became simple transaction scripts.
Very interested to see your approach to the task. It'd be pretty cool if all the prominent UA-camrs were to tackle the same domain problem. Everyone could learn new approaches and strengths and weaknesses of the designs clearly.
The problem is all examples are simplified and made up with little complexity, which isn't what most projects/products are like.
@@CodeOpinion thats so true
If we're talking about DDD, the problem is with most of the books or resources, that they are too abstract. That is mostly from what I've seen. DDD is hard entry barrier for not only beginners but also more senior developers since books don't provide many in-code examples. Recently, I have been reading a DDD good book by Vladik Khononov, and that one breaks that tendency a bit, which I find personally great.
I've mentioned this a bunch, but for anyone reading again, the issue is providing a context with enough domain complexity to warrant it. Nobody is going to sit through hours of explanation of a complex domain. You have to be abstract enough and the reader/viewer has to hopefully fill in the blanks (correctly) about what "complexity" actually is. Unfortunately, that doesn't seem to happen and patterns/practices are used when it's not justified.
I should have rather used “concrete” than in-code, in the afterthought. But, Stack overflow is filled with basic questions on DDD and not even the complex bits. One of the common complains I hear related to DDD is that “no one knows how to implement this right” which is recurring. For me personally, if I had to start learning it anew from scratch, it would help to sit through an elaborate example of complex domain in form of a workshop or something alike, since it can alleviate most, if not all the questions in a single session.
I'm really looking forward to learn, how you would design the system
The problem starts with jumping straight to aggregates before you've worked with the business to understand the actions and events of your system. You can't understand your service boundaries, much less your aggregates, until you have worked out the process and events with the business.
Amichai Mantinband's videos are really focused on defining data structures and not primarily modeling entities with their behavior. Entity here is just a fancy word for an instance of a data class. Why even mention the Id:s? They are an implementation detail and not necessarily part of the model. I know how easy it is as a programmer to jump on implementing something. But the point of DDD is to figure out what to build - and not structuring your code.
Understanding the domain and modeling that in code as relatable as possible. There will always be technicalities in code but more often then not theres not a single model or a single representation that servers all purposes. This wasn't a review so much of that video as using it as inspiration for my own of what I wanted to illustrate.
@@CodeOpinion Sure. I know that. And these were just my immediate thoughts when you mentioned it. I do however think that context is important while modeling. And to keep it balanced. Your model is a representation and don’t let the technical details distract you. Which often happens in these examples.
@@marna_li So many toy examples leave out technical details to the point of uselessness. I'd rather see too many details than not enough. Furthermore, leaving off details can make the design appear cleaner than it actually is once you go to implement it.
For example, one thing I really do like about this channel is he mentions technical concerns like consistency, whereas so many examples just completely ignore it.
@@bobbycrosby9765 I meant that it focus a lot on how it is being implemented rather than how to approach software development in terms of organising and finding a structure that lets the project and codebase evolve.
Yeah. Consistency and such is seldom taked about in other channels. It is quickly skipped over and taken for granted. I guess the point is that other samples are not complex enough.
But to understand stuff, perhaps more in-depth technical examples are great. Not just as part of some mega reference project.
Yes, agree with you, that's the way, indeed. Great video. Thanks
Funny I don’t know anything about DDD but I wanted to comment that you should start the design from the actions you want to be able to get or do as a user until he said it himself.
When you say behaviors, I guess you mean application commands (like in CQRS). Right?
Commands, Actions, Workflows, Intent.
This seems like it's going to create tons of technical debt and will pull on the proverbial string when the behaviors/actions inevitably need to be modified or are simply deleted because a process is no longer needed.
looking forward for the follow up
Is a "User" really an entity? I often question things like this because the concept of a "user" is not actually part of the problem domain, but something that came into existence when we are trying to automate the solution. Just a curiosity, great video as usual!
It depends. If you can swap out all the attributes on a user with another user and they can be treated equal then it's not an entity.
Good topic with continuation. It is the best way to make people(at least me) to subscribe. Thanks!
If you watch enough of my videos, you'll notice an underlying thread (continuation). They all relatively relate to each other in the grand scheme of things.
@@CodeOpinion yes I noticed, but this feels like good seial episode which finished on the best part :)
so what book is the top one - the bottom one I have :D
The Art of Community
Good video. Again.
Jeez, Derek, the high quality of your content is getting oh-so-monotonous.... 😀
Yup...understanding the transactional / consistency boundaries in your system is driven by understanding the behaviours within your system that require consistency to be maintained. And then starting to think about Aggregate Roots.
On the other hand, beginning with your domain objects and data structures rather than behaviours will have you scratching your head pretty quickly in anything other than the most simple systems. At some point a new behaviour will come along that will have you jumping through hoops with your domain model. And probably refactoring regularly as you discover the cascade of unintended complexities that you may have introduced by starting from the wrong place.
And then comes the the *next* behaviour that has you doing the same thing all over again (but this time with possibly even more complexity and hoops to jump though) until you realise that starting with behaviours first was the best way to go right from the start.
I look forward to your follow-on video!
Thanks. A lot of what I was describing is one step farther from "entity services", which is why things become highly coupled. If you have the concept of entity that exists solely exists in one aggregate, you then need to reference that aggregate because it contains all the data for everything "related" to it.
@@CodeOpinion Indeed.
thanks
Nice to see Amichai's perspective being challenged. I knew something was off from the get-go.
I wouldn't view it that way really. I don't. It's more of taking the example used and elaborating on it.
Great video. I'm looking forward to the follow-up video.
Coming soon!
7:37 Create a video? That's pretty CRUDdy
CRUDy in areas, Task driven in others.
BubberDinner
In summary, do TDD/BDD.
Somewhat. Build your entities based on behaviors and the data required for those behaviors, not the other way around.