3 Steps for Modeling a Complex Domain | CLEAN ARCHITECTURE & DDD From Scratch Tutorial | Part 11

  Рет қаралды 51,115

Amichai Mantinband

Amichai Mantinband

Күн бұрын

Пікірлер: 57
@amantinband
@amantinband 2 жыл бұрын
To recap: 1. Identify Entities and treat each entity as an aggregate root 2. Identify relationships between the entities 3. Merge aggregates if there are constraints Possible constraints: 1. Enforcing Invariants 2. Eventual consistency cannot be tolerated Good indicators that an entity should be an aggregate root: 1. It is referenced by other aggregates 2. It will be looked up by Id Curious to hear what you think!
@kevlingo
@kevlingo 2 жыл бұрын
I'm obsessed with you...but not in a creepy way 😁 You have a way of simplifying things without dumbing them down. That's a tough thing to do. I am waiting with baited breath for more in this series. PURE GOLD!!
@amantinband
@amantinband 2 жыл бұрын
😂😂😂
@leuras-dev
@leuras-dev Жыл бұрын
This playlist is the best content about DDD available on KZbin!!!! Thank you!
@alvin3171997
@alvin3171997 2 жыл бұрын
I’ve read “implementing domain driven design” book but always feel lost in some part, this series clear things up tremendously! Thank you sir 💯
@maexoman
@maexoman 2 жыл бұрын
This is one of the best videos I’ve found explaining how to model the domain. I’m a complete beginner in DDD so this step by step guide helps a lot! Thank you so much! I still have one question left though. I understand your decision to make the reservation be part of the dinner. Doesn’t it become a performance bottleneck at some point? How would you handle something like a concert where you wouldn’t like to sell more tickets than you have. So the tickets would be part of the Concert aggregate but wouldn’t it be unreasonable to load like 50k rows just to check not that it won’t be overbooked after adding another purchase? Would you use lazy loading and a counter in this scenario?
@tenzl
@tenzl Жыл бұрын
it's been 3 months and no reply. Did you happen to find an answer to your question since then? I'm also wondering the same thing.
@greggles_b
@greggles_b Жыл бұрын
You’d have to go with an eventually consistent approach: - Create a Reservation in an REQUESTED state (pick whatever name best fits your domain). Publish a ReservationRequested domain event. - Whenever ReservationRequested, invoke domain logic of the Dinner aggregate (in a separate unit of work), I.e. HandleReservation. - The Dinner aggregate keeps a list of accepted reservation id’s so it can determine whether the capacity limit has been reached. Publish a domain event DinnerReservationHandled with the result. (You have a choice here whether to have separate events for accepted/rejected, or whether to model them as one event. Either way you need the event to update the Reservation to its final state. You can likely find better domain language to use than “Handle/Handled”) - Whenever DinnerReservationHandled, invoke the Reservation aggregate to update its state to ACCEPTED or REJECTED. To implement this workflow you can use an event-driven or orchestrated workflow. I’d likely avoided events and go with the latter since you’re always likely to have edge cases, such as what happens if the guest cancels their reservation after the Dinner aggregate accepts it but before the Reservation is updated. Or if the host changes the venues capacity… These are valid workflows in themselves and may require the use of the Saga pattern to undo the action on the Dinner and perhaps invoke subworkflows, like cancelling someone’s reservation. I just think integration events can get super complicated and you can lose track of the high level business processes in a web of events. Take a look at Temporal.IO or Camunda for workflow orchestrators.
@felipeklafke
@felipeklafke Жыл бұрын
impressão minha ou você iniciou a modelagem justamente da forma que o livro azul nao indica?
@1981ilyha
@1981ilyha 2 жыл бұрын
Wow! Amazing presentation - it looks sooo simple! Thank you!!!
@amantinband
@amantinband 2 жыл бұрын
Happy you liked it 🙂
@samirahmad248
@samirahmad248 10 ай бұрын
Hey, I wanna thank you for this series, it helped me alot. But forgive me for my long question because I am really confused: 🔷is the Host id and Guest id are really needed in the User aggregate ?? 🔷how should I implement the authorization and authentication if so, should i add the password, email... properties to the user aggregate??.. 🔷Since the Host and the Guest have different bussiness rules, how should i implement this? should it be implemented in the Domain services (the Application layer) or in the Domain layer where i can add some rules to the aggregate itself? 🔷can one aggregate inherit from another one? like the Host inherting from the user aggregate?
@amanamudoaka8020
@amanamudoaka8020 2 жыл бұрын
Thanks a lots, you are opening our eyes. Please do something on ubiquitous language (UL). How we can create one and use it to tie analysis model to code model. It would be a big boost for me. Shis you just opened me eyes. Thanks a lot.
@amantinband
@amantinband 2 жыл бұрын
I’ll add it to my backlog 🤙🏼
@amanamudoaka8020
@amanamudoaka8020 2 жыл бұрын
Okay. BIG up
@spottedmahn
@spottedmahn Жыл бұрын
Thanks for using dark mode for the visualizations!
@frankoppermann1877
@frankoppermann1877 Жыл бұрын
I have a question to the relashionships. Example with Menu and Dinner: In the Menu, you are referencing a collection of DinnerIds. In the Dinner, you are referencing the MenuId. What, if you add a Dinner and forget to add the DinnerId to the referenced Menu? Where is the correct relationship stored? In the DinnerId-Collection in the Menu or in the MenuId-Field in the Dinner? I think, a clean way is to store the parent menuId in the Dinner. The collection in the Menu should not be used. If you want to get all Dinners related to a Menu, you can filter the Dinner-Aggregates by MenuId. The single point of truth. If you also can ask the Menu-Aggregate for the result, you can possibly get another result. How should the relashionships be handled in a clean and correct way?
@carmineos
@carmineos 2 жыл бұрын
Great video as usual, I'm loving this series
@kmcdo
@kmcdo 2 жыл бұрын
Another fantastic video! Keep up the great work!
@amantinband
@amantinband 2 жыл бұрын
Thanks, Kyle!
@David-rz4vc
@David-rz4vc 9 ай бұрын
you're so good at explaining
@srinivaspitani1326
@srinivaspitani1326 4 ай бұрын
Buddy... I will suggest google to allow a ton of likes from each person only for your videos ;) Loved it!
@smliwhcirdeirf
@smliwhcirdeirf Жыл бұрын
I'm wondering why the menu item (in sections) isn't its own entity and is also just referenced with the id like dinner is.
2 жыл бұрын
That's a really great content, thanks for sharing it. How would you go about documenting about side-effects happening in an aggreate (domain events)?
@amantinband
@amantinband 2 жыл бұрын
Thanks, Arley. The aggregate markdown file is a natural place to put all aggregate-related details. We'll cover Domain Layer folder structure in a video next week, but generally, the approach I use nowadays is: > Domain > Aggregate Type (for example 'Dinner') > Entities > Enums > Events > ValueObjects So if the Domain Event documentation only lists the domain events, it might be simpler to look under the Aggregate's Events folder.
@FernandoLopez-rd8jv
@FernandoLopez-rd8jv 5 ай бұрын
question. Is having the average rating as a property of your menu really needed? What invariant/behavior does it satisfy? It to me looks more like a read model property. Not sure If I am making sense here.
@davemasters
@davemasters 2 жыл бұрын
Another fantastic video. I think designing aggregates is really the essence of DDD.
@amantinband
@amantinband 2 жыл бұрын
Thanks, David! I actually think that's a misconception 🫣
@davemasters
@davemasters 2 жыл бұрын
@@amantinband really? how so? I've always felt like people tend to focus on "layers" and implementing repositories/factories etc rather than thinking about defining transaction boundaries
@amantinband
@amantinband 2 жыл бұрын
I agree that aggregates are an essential part of DDD. I'm referring to the misconception that "DDD" == "tactical patterns," not considering many other practices and strategic design patterns.
@nareshyalagala
@nareshyalagala 11 ай бұрын
Whats the software you are using to create these nice design?
@dandogamer
@dandogamer Жыл бұрын
Maybe I need to go back and watch some videos that describe entities and aggregates because I was getting a lil lost here. But this just looks like SQL modelling to me...
@pilotboba
@pilotboba 2 жыл бұрын
So, one thing I have sort of understood from my early diving into DDD is that an Entity is meaningless without context. So, customer means something completely different in the Sales context vs the Finance context. So, maybe I'm confused when you say the dinner will be a value object in some other aggregate, but then on your model diagram, you list it is DinnerId... which sounds like a reference. I thought a value object had no idea, it was differentiated by it's values, not by it's id. Perhaps when you get into code this will make more sense, but it's not clicking for me right now.
@amantinband
@amantinband 2 жыл бұрын
Hey Bob, missed your insights in the last few videos! 🙂 Sort of. I would say the following: 1. Terms (anything from Aggregates/Entities/enum values to general terminology) have meaning only within a bounded context, so 2 terms can have different meanings depending on the context. 2. If aggregates need to reference each other, they do it by id. 3. Entities are identified by their id. 4. Value Objects are identified by their value. 5. An Aggregates id must be unique within the bounded context. 6. A local Entity's id must be unique only within its parent aggregate. In the video, we have a single Bounded Context. This means that each term has a single meaning within our Domain layer. When our various Aggregates reference one another, they do so by id. If we have the following (notice the id of Aggregate 2 is a number, not a string): Aggregate 1: { "id": "1" } Aggregate 2: { "id": 2 } If we want to reference 2 from 1, we can either create a property to contain it: Aggregate 1: { "id": "1", "otherAggregate": "2" } Or, create a value object that contains the id. And store that instead. For example: class OtherAggregateId { public int Value { get; set; } // Aggregate 2's id value object definition Aggregate 1: { "id": "1", "otherAggregate": { "value": 2 } } This abstraction layer allows us to update Aggregate 2's id type/structure without updating all referencing entities. It also allows us to encapsulate id generation logic for example: $"Reservation_{GuestId}_{DinnerId}" Does that make sense?
@gzoechi
@gzoechi Жыл бұрын
Great videos. Where can I find the link to the tool you are using? I couldn't find anything in the video description.
@gzoechi
@gzoechi Жыл бұрын
It looks like you are still using Figma but with a custom template?
@codingsavid6509
@codingsavid6509 10 ай бұрын
Best video regarding this, you're a goat
@anaredbeard6052
@anaredbeard6052 Жыл бұрын
Hi, Amichai! Could you please explain why "Section" and "SectionItem" are not present in the "relationships" part?
@roberteru25
@roberteru25 Жыл бұрын
Ok, what if the guest want to find all reservation, does it mean the guest will first list the dinners before getting to the reservations ?
@Joshiii211
@Joshiii211 2 жыл бұрын
Super informative video, thanks for making this! What tool are you using or what tools can you recommend to visualize the modeling process? I don't really understand the first approach you are describing at 13:36. If we create another entity under guest, wouldn't that be a mirroring of the reservation entity and introduce eventual consistency problems? Or did i understand your approach wrong?
@amantinband
@amantinband 2 жыл бұрын
Thanks, Lycosh! The first approach would be creating a new entity/value object, for example "UpcomingReservation", that would contain the relevant properties. Then, reserving a dinner would raise the "DinnerReserved" domain event. This event would trigger a handler that would result in the Guest entity having a new UpcomingReservation object. Like you said, the Guest entity will be eventually consistent. Does that make sense?
@amantinband
@amantinband 2 жыл бұрын
Regarding visualization, I created the following figma community tool for process modeling: www.figma.com/community/file/1153317295146512523
@Joshiii211
@Joshiii211 2 жыл бұрын
@@amantinband Yes it does, thank you
@jameskelly99
@jameskelly99 2 жыл бұрын
Perfect timing, I am working with an aggregate currently that has got too big and was wondering how to break it down…I knew the theory, but had struggled with implementation. You have shown me exactly how to go about it so I can easily implement! Thanks a heap!
@AshiqurRahman-q3w
@AshiqurRahman-q3w Жыл бұрын
Great series. On an unrelated note, how are you making the JSON autocomplete?
@PepeFlores97
@PepeFlores97 Жыл бұрын
GitHub copilot
@SenthilKumar-lj5cw
@SenthilKumar-lj5cw 2 жыл бұрын
keren, sehat selalu bang, ditunggu share cara instal aplikasi macbook yang lain
@AdrianStanula86
@AdrianStanula86 Жыл бұрын
Great series! What tool do you use for "always on top" functionality?
@krccmsitp2884
@krccmsitp2884 Жыл бұрын
I guest it's from Microsoft PowerToys.
@spottedmahn
@spottedmahn Жыл бұрын
What tool are you using for your visualizations? I like it! Great content, thanks!
@spottedmahn
@spottedmahn Жыл бұрын
NVM, Figma!
@spottedmahn
@spottedmahn Жыл бұрын
But what tool for drawing the temporary arrows, boxes, etc? 🤔 That’s not Figma I’m guessing
@gaxkiller
@gaxkiller 11 ай бұрын
Wow, dude this is so helful !
@vahidalizadeh5836
@vahidalizadeh5836 Жыл бұрын
Hi there. Thank you for this great tutorial. I have a question. How could I do the migration in ef core with aggregate root?
@alexdorand
@alexdorand Жыл бұрын
amazing
@m_camper
@m_camper Жыл бұрын
after this video I had to go to the kitchen and make myself smth to eat :)
@amantinband
@amantinband Жыл бұрын
😁
When mom gets home, but you're in rollerblades.
00:40
Daniel LaBelle
Рет қаралды 132 МЛН
UFC 308 : Уиттакер VS Чимаев
01:54
Setanta Sports UFC
Рет қаралды 933 М.
3 Powerful Design Patterns You Should Know About
14:26
Amichai Mantinband
Рет қаралды 623
Modeling a Domain With Domain-Driven Design From Scratch | DDD
19:10
Milan Jovanović
Рет қаралды 91 М.
Domain-Driven Design: The Last Explanation You'll Ever Need
21:05
Software Developer Diaries
Рет қаралды 8 М.
Domain Modeling with Domain-Driven Design (From Scratch)
18:05
Milan Jovanović
Рет қаралды 26 М.
Clean Architecture vs Domain-Driven Design (DDD) - Understand the Difference
11:26
Introduction to Context Mapping - Michael Plöd - DDD Europe 2022
59:15
Domain-Driven Design Europe
Рет қаралды 22 М.