Love your videos, just a little tip, on mobile the red line at the bottom implies that I’ve already viewed the video. I almost skipped past the video because of it.
Great video! Loved that you also talked about what “complexity” could look like. Here’s another take on DDD vs. CRUD: DDD sets you up for applying the things you learn on top of the code you already wrote. CRUD sets you up for redoing the stuff you wrote after you learn things. People that use CRUD generally underestimate the complexity, and have a hard time throwing away their code (and simple mental model). It remains an issue to explain why you could go super fast delivering features in the beginning and you can’t anymore in CRUD. At least in DDD you build with more clear assumptions, and with a more predictable albeit slower pace.
Yes, I think that's an important point is that if you start with CRUD, you need to know when you're crossing the line of complexity it can handle. For a variety of reasons, I believe that may occur but instead of refactoring, it's trying to shove the complexity into the existing code/model. As I of mentioned, one model doesn't need to rule them all.
IMO the whole CRUD vs "domain model" comes mostly from the tension of developers abandoning classic OO design to write procedural / imperative code on top of an OO language - which tends to be the norm these days -. Proper encapsulation and abstractions seem to have been turned into some kind of trade-off, only to be embraced at some specific scenarios. Then, what's the point of using OOP langs for all these projects?
Because most of the mainstream languages are OO, "class first", but as you mentioned most probably write procedural code in a lot of cases. I actually tend to favor a lot of functional concepts in my own code while being in a OO first language (C#). Meaning, I don't think there is a need for doing everything in "pure OO" fashion. Speaking for myself, I think I should make the jump to F# but that's a different conversation.
Yes. And honestly, my favorite languages to do OOP in aren't really OOP languages. If you've never used Common Lisp, CLOS (OOP in common lisp) is a piece of heaven. Not saying you need to use Common Lisp professionally, but it's awesome for side projects, and if all you've used are the standard imperative languages, oh boy, there's a wide, wide world out there.
I’ve come across solutions where they’ve tried to use DDD and micro services etc, when all there is is a data pipeline that should take data from sources x, y and a and then just put it somewhere for lookup. That to me is definitely adding complexity where it is not needed.
I only consider CRUD applications to literally be frontends for a database table without any rules. As soon as there are rules, basically starting with one if put in there somewhere, I create a domain model. It gives me so much peace of mind, freedom of change, clear boundaries and supreme testability.
I would love to see a more detailed outline of domain model vs transaction scripts. Are those necessarily mutually exclusive? Can't I use richer models from mediator handlers?
Not all boundaries are created equal. Some are apart of your core domain, have a lot of complexity. Others are more in a supporting role and are just CRUD. While others are more of a commodity and can be purchased and integrated into.
Great video as always, but no matter how "not complex" the domain is, if CRUD is done poorly it will have adverse effects like some aspects of the domain leaking into the user interface or even stored procedures inside the DBMS itself.
DDD sounds like you need to use an iterative process to work with it. The domain expert isn't going to be available 24/7 and complexity in larger projects can evolve quickly. Are there any start to finish real world examples that are publicly available?
As I watched you add extra complexity to your use cases, I started to wonder whether adopting a pattern like CQRS/ES actually makes the modeling simpler and open to the gradual introduction of those more complex workflows vs a third normal form/CRUD style of modeling especially in terms of migrating/evolving the object models and persistence. I'm not well versed enough in CQRS/ES to feel confident in my answer, but I tend to think that it might be the case. What do you think?
Could an indication of complexity be whether or not the business rules are modeled by conceptual abstractions that do not or would not have a corresponding database table/collection? Consider your logistics example: any given truck could be viewed as a graph, any given pickup or dropoff event as a vertex, and any given shipment a path across the graph (with legs corresponding to edges). It seems like graph algorithms would be very useful, but a graph itself requires at least two tables and neither of them is useful in the context of graph theory without the other. Does my question make sense in this light? As usual, tyanks for another great video. And as usual, the topic is immediately relevant to what I'm trying to figure out 😂
I think the main issue is in the transition of CRUD -> Domain model that Derek has described. When you have only raw CRUD data, you think about database design, because there's not much more to think about. In the process of getting the workflow from users heads into software, you suddenly transition into modeling state machines, where before you were building mostly static data models. That's where I see most people trip up - model is by definition bounded to a certain purpose/application, and while there needs to be mapping between data and domain model, those are really separate things. Graph modeling is indeed very useful for logistics, but again, model has a specific purpose. For example, when you model the feature of combining multiple shipments into a route, you are solving travelling salesman problem, in which graphs are a very handy tool. But in that situation you most certainly don't want to care about how the data is persisted. Personally, I would consider the heuristics of 'business rules that are hard to model via relational db' as a decent rule of thumb.
Nodding. CRUD is data centric and moving more to behavior/capability centric is very different. When I was talking about doing the Pickup and the Delivery, those are very domain specific actions. I didn't go full out in using the actual terminology in this video but generally when you're talking to people that live in this industry, they're not talking about "entities" so much as they are talking about events.
In a proper relational database schema design, business relationships are also modeled in the database. If the relationships are a graph, perhaps a graph database is more suited than a relational database.
Do you struggle with figuring out if you have "a lot" of complexity? Does everything seem like it should fit in CRUD?
Love your videos, just a little tip, on mobile the red line at the bottom implies that I’ve already viewed the video. I almost skipped past the video because of it.
Good call! let me fix that!
Getting UX lessons here too
Great video! Loved that you also talked about what “complexity” could look like.
Here’s another take on DDD vs. CRUD: DDD sets you up for applying the things you learn on top of the code you already wrote. CRUD sets you up for redoing the stuff you wrote after you learn things. People that use CRUD generally underestimate the complexity, and have a hard time throwing away their code (and simple mental model).
It remains an issue to explain why you could go super fast delivering features in the beginning and you can’t anymore in CRUD. At least in DDD you build with more clear assumptions, and with a more predictable albeit slower pace.
Yes, I think that's an important point is that if you start with CRUD, you need to know when you're crossing the line of complexity it can handle. For a variety of reasons, I believe that may occur but instead of refactoring, it's trying to shove the complexity into the existing code/model. As I of mentioned, one model doesn't need to rule them all.
IMO the whole CRUD vs "domain model" comes mostly from the tension of developers abandoning classic OO design to write procedural / imperative code on top of an OO language - which tends to be the norm these days -. Proper encapsulation and abstractions seem to have been turned into some kind of trade-off, only to be embraced at some specific scenarios. Then, what's the point of using OOP langs for all these projects?
Yup this is actually the real question, why do we even use OO design?
Because most of the mainstream languages are OO, "class first", but as you mentioned most probably write procedural code in a lot of cases. I actually tend to favor a lot of functional concepts in my own code while being in a OO first language (C#). Meaning, I don't think there is a need for doing everything in "pure OO" fashion. Speaking for myself, I think I should make the jump to F# but that's a different conversation.
Yes F# for the win!!!
@@CodeOpinion Haha yes F# looks very promising for DDD, just not sure how mature the ecosystem is (e.g. for graphql servers)
Yes.
And honestly, my favorite languages to do OOP in aren't really OOP languages.
If you've never used Common Lisp, CLOS (OOP in common lisp) is a piece of heaven. Not saying you need to use Common Lisp professionally, but it's awesome for side projects, and if all you've used are the standard imperative languages, oh boy, there's a wide, wide world out there.
I’ve come across solutions where they’ve tried to use DDD and micro services etc, when all there is is a data pipeline that should take data from sources x, y and a and then just put it somewhere for lookup. That to me is definitely adding complexity where it is not needed.
Ya, I'd be curious the number of projects that "apply tactical" DDD but really shouldn't.
I only consider CRUD applications to literally be frontends for a database table without any rules. As soon as there are rules, basically starting with one if put in there somewhere, I create a domain model. It gives me so much peace of mind, freedom of change, clear boundaries and supreme testability.
I would love to see a more detailed outline of domain model vs transaction scripts.
Are those necessarily mutually exclusive? Can't I use richer models from mediator handlers?
Check out this video: ua-cam.com/video/PrJIMTZsbDw/v-deo.html
What are your feelings on a hybrid model whereby some of the logic can be crud and other logic is more crud based? Separate service/boundary?
Not all boundaries are created equal. Some are apart of your core domain, have a lot of complexity. Others are more in a supporting role and are just CRUD. While others are more of a commodity and can be purchased and integrated into.
Great video as always, but no matter how "not complex" the domain is, if CRUD is done poorly it will have adverse effects like some aspects of the domain leaking into the user interface or even stored procedures inside the DBMS itself.
Anything done poorly will have adverse effects 😂. With CRUD leaking your data model all the way to the Client/UI will have a negative effect.
DDD sounds like you need to use an iterative process to work with it. The domain expert isn't going to be available 24/7 and complexity in larger projects can evolve quickly. Are there any start to finish real world examples that are publicly available?
As I watched you add extra complexity to your use cases, I started to wonder whether adopting a pattern like CQRS/ES actually makes the modeling simpler and open to the gradual introduction of those more complex workflows vs a third normal form/CRUD style of modeling especially in terms of migrating/evolving the object models and persistence. I'm not well versed enough in CQRS/ES to feel confident in my answer, but I tend to think that it might be the case. What do you think?
CQRS in general without event sourcing has a bunch of benefits. I talk about it in this video: ua-cam.com/video/dvnZfSK4dBI/v-deo.html
thanks for the video. good example.
Could an indication of complexity be whether or not the business rules are modeled by conceptual abstractions that do not or would not have a corresponding database table/collection?
Consider your logistics example: any given truck could be viewed as a graph, any given pickup or dropoff event as a vertex, and any given shipment a path across the graph (with legs corresponding to edges). It seems like graph algorithms would be very useful, but a graph itself requires at least two tables and neither of them is useful in the context of graph theory without the other. Does my question make sense in this light?
As usual, tyanks for another great video. And as usual, the topic is immediately relevant to what I'm trying to figure out 😂
I think the main issue is in the transition of CRUD -> Domain model that Derek has described. When you have only raw CRUD data, you think about database design, because there's not much more to think about. In the process of getting the workflow from users heads into software, you suddenly transition into modeling state machines, where before you were building mostly static data models.
That's where I see most people trip up - model is by definition bounded to a certain purpose/application, and while there needs to be mapping between data and domain model, those are really separate things.
Graph modeling is indeed very useful for logistics, but again, model has a specific purpose. For example, when you model the feature of combining multiple shipments into a route, you are solving travelling salesman problem, in which graphs are a very handy tool. But in that situation you most certainly don't want to care about how the data is persisted.
Personally, I would consider the heuristics of 'business rules that are hard to model via relational db' as a decent rule of thumb.
Nodding. CRUD is data centric and moving more to behavior/capability centric is very different. When I was talking about doing the Pickup and the Delivery, those are very domain specific actions. I didn't go full out in using the actual terminology in this video but generally when you're talking to people that live in this industry, they're not talking about "entities" so much as they are talking about events.
In a proper relational database schema design, business relationships are also modeled in the database. If the relationships are a graph, perhaps a graph database is more suited than a relational database.
😎 👍 awesome. Where did you learn to model logistics so well? Any resources? I would really appreciate it
Experience in the domain.
crud its about create read update delete, ddd has too, its better say vs mvc or something architectural
It's about managing and performing state changes and enforcing invariants. MVC is a separation of concerns.
I see, we can choose between crud model or domain model based on complexity. but what are crud model and domain model? 🤔
Check out this video where I talk about complexity in CRUD and moving away from it: ua-cam.com/video/kalD8TcRBCc/v-deo.html
Great video!
Thanks!
Cool comments here, we have primitive type obsession at work, another reason for ddd. Write some value objects guys.