Тёмный

Aggregate Design: Using Invariants as a Guide 

CodeOpinion
Подписаться 85 тыс.
Просмотров 38 тыс.
50% 1

How do you compose an aggregate? For me aggregate design involves understanding the invariants. Invariants are business rules that must always be consistent.
🔔 Subscribe: / @codeopinion
💥 Join this channel to get access to source code & demos!
/ @codeopinion
🔥 Don't have the JOIN button? Support me on Patreon!
/ codeopinion
📝 Blog: codeopinion.com
👋 Twitter: / codeopinion
✨ LinkedIn: / dcomartin
0:00 Intro
1:32 Aggregates
2:11 Invariants
3:33 Code Example
7:38 Recommendations
#softwarearchitecture #softwaredesign #domaindrivendesign

Наука

Опубликовано:

 

1 авг 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 69   
@skipodap1
@skipodap1 3 года назад
"Don't expose domain objects that can't enforce the business rules". That closing sentence was brilliant. Thanks for the vids
@CodeOpinion
@CodeOpinion 3 года назад
You're welcome
@RobLang
@RobLang 3 года назад
Been using DDD for over 10 years, popped in for a new take and although this confirmed what I knew, I just applaud and say it was explained brilliantly!
@CodeOpinion
@CodeOpinion 3 года назад
Thanks. Appreciate the comment.
@jacobmason6761
@jacobmason6761 3 года назад
I rarely ever comment on RU-vid videos, but this is well deserved. You're concise and straight to the point, fantastic content. I struggled to find video resources on DDD and resorted to books, I wish this content was here when I first started learning. Please keep doing what you're doing!
@CodeOpinion
@CodeOpinion 3 года назад
I really appreciate the comment. Thanks!
@xbmcme9768
@xbmcme9768 2 года назад
Really like the concrete examples. It's really hard to imagine a technical implementation of different concepts that I've never seen before in my life. Thanks for taking the time to make these videos. They are super helpful!
@CodeOpinion
@CodeOpinion 2 года назад
Glad you liked it!
@kozer1986
@kozer1986 2 года назад
I'm crying of joy!!! Amazing channel. What I was looking for to grasp ddd more!
@CodeOpinion
@CodeOpinion 2 года назад
Thanks! Hopefully the videos help.
@secondry2
@secondry2 3 года назад
Since watching your videos my code quality has improved 10-fold and performs 10x better, not an exaggeration. Keep it up, loving the videos!
@CodeOpinion
@CodeOpinion 3 года назад
Glad they are helpful!
@ToeShimmel
@ToeShimmel 2 года назад
Your video's are fantastic. I keep coming back and they make me a much better developer. Thanks so much. You deserve more views!
@CodeOpinion
@CodeOpinion 2 года назад
Much appreciated!
@NomadicBrian
@NomadicBrian 2 года назад
Excellent presentation. Walked away with a much clearer understanding of Aggregates.
@CodeOpinion
@CodeOpinion 2 года назад
Glad it was helpful!
@hesamkashefi
@hesamkashefi 3 года назад
Very good explanation. For me, the harder problem is how to find aggregate roots and their boundaries in a real-world project, it would be a very helpful video if you could make it for us.
@CodeOpinion
@CodeOpinion 3 года назад
Find the invariants. Find out what the behaviors are and the data behind them. Map the actual workflow of the domain.
@michaelwong1908
@michaelwong1908 3 года назад
That's clearly explained! Wish I have learnt this earlier.
@CodeOpinion
@CodeOpinion 3 года назад
I guess I should of posted it sooner 😀. Glad it helped.
@MrSpyTubes
@MrSpyTubes 2 года назад
🙏 thanks for your great work.
@victortodoran1828
@victortodoran1828 2 года назад
Ok, this one I had to watch three times, but I really enjoyed it in the end. This was a well picked example, the implementation is pretty nifty and smart and some good points were made. I did not care for what I supose is ddd lingo, but I gues that is on me to learn. Thanks for taking the time.
@CodeOpinion
@CodeOpinion 2 года назад
I try and avoid certain type of lingo but sometimes it's unavoidable or I do a poor job and assume it's common. Appreciate you watching and the feedback!
@JohnnysaidWhat
@JohnnysaidWhat Год назад
These videos are where you go when you fight the final boss of EDD. So good but so technical.
@Eugene.g
@Eugene.g 3 года назад
I wish my code was that clean and readable
@CodeOpinion
@CodeOpinion 3 года назад
Glad you thought it was readable 😀 I actually left some of the code without using some of the new C# features to not throw people off.
@kylegivler8372
@kylegivler8372 9 месяцев назад
Thanks!
@CodeOpinion
@CodeOpinion 9 месяцев назад
Thank you!
@tarreislam
@tarreislam 2 года назад
Thanks
@lost-prototype
@lost-prototype 2 года назад
Great video! A quick question... Do you ever create extension methods on generic collection types of your domain models to represent certain filters or operations?
@CodeOpinion
@CodeOpinion 2 года назад
I'm trying to think if I have for domain objects. I don't think so but I generally create extension methods when I don't want to pollute the focus of the initial API. Usually for some specialized reason.
@vakul_18k55
@vakul_18k55 2 года назад
Inside the stop class. We have sequence as primitive. Should we create it as a value type? From what I have seen DDD says we should not have primitives
@williamsbotchway2471
@williamsbotchway2471 Год назад
Hi Dereck i am new to ddd but i have question on the video. Since u are passing a collection of stops to the constructer of the shipment aggregate, it means clients other than the shipment aggregate can call both the arrive and isComplete methods thereby resulting in inconsistent state, by passing the rules defined in the shipment aggregate? Does this means a refinement of what is needed to enforce the invariant is needed? Pls answer on this. Also one general rule is that entities inside an aggregate can only be reference by other aggregate by holding a transient copy of these entities. I think passing a collection of stops as shown in the videos violate this general rule. however domain services can be used to defined previousStopAreNotDeparted and used as client in stop which should be treated as aggregate. If this approach is corrected should we have two distinct aggreagete for PickupStop and DeliveryStop. Again i am a novice to ddd so please advice. Thank u.
@ivanmiroshnichenko4299
@ivanmiroshnichenko4299 2 года назад
As far as I understood, if I have a 'manager' class which has a couple of methods such as 'Run()' something or 'Stop()' something is an aggregate class, isn't it?
@CodeOpinion
@CodeOpinion 2 года назад
That's not enough for me to define if it's an aggregate. An aggregate is a collection of related objects that form a consistency boundary.
@thedacian123
@thedacian123 2 года назад
Spotting boundaries is a complicated stuff,and DDD in general which leads to domain experts/analists comitmment.But what should we do if business people are not too cooperant?Thanks
@CodeOpinion
@CodeOpinion 2 года назад
Ya it's a good question and one I've gotten over the years. Anything is difficult if you aren't going to have buy in and cooperation.
@futurexjam2
@futurexjam2 11 месяцев назад
you can apply BPM(business process management) approach. By BPM approach you can easily change the flow between states even binding coniditional transitions.
@dansharpe4535
@dansharpe4535 3 года назад
i have a quick question around the Stop classes, in terms of other stop information, location, opening times etc, would you have another, fuller entity/aggregate? and if the shipment required things like opening times for its business logic (eg to check its open on the shipment day), how would you do this? would you load the full entity/aggregate and pass this information in as part of the command or have i missed a concept?
@CodeOpinion
@CodeOpinion 3 года назад
So for me it depends if you need that data for invariants (business logic). If you don't, my aggregates are generally for write/command purposes, not queries. If that's the case, then if you don't need it for invariants, then you don't need it in the aggregate. If you do need other data that isn't apart of the aggregate, and you don't think it should be apart of it (opening times), then you can always pass that data (or double dispatch) when you call a method on the aggregate that needs it eg, ArriveStop(PlaceValue) or ArriveStop(stopId, Places.GetOpeningTimeDelegate) or ArriveStop(stopID, IPlaces)
@dansharpe4535
@dansharpe4535 3 года назад
@@CodeOpinion thanks for that reply, it really helps, sometimes i just struggle a bit with what ok to pass into a method within your aggregate (like additional info to help with business logic) or does that then create a dependency on something outside of the aggregate?
@CodeOpinion
@CodeOpinion 3 года назад
Nothing wrong with passing what you need so as long as you understand the coupling. Double dispatch as well isn't inherently bad.
@dansharpe4535
@dansharpe4535 3 года назад
@@CodeOpinion that makes sense, as if the call to get opening times fails, then you cant validate your business logic at that point but the logic is still encapsulated within the aggregate :)
@alfonsdeda8912
@alfonsdeda8912 5 месяцев назад
Hi Derek, i use ef core for my database and in one service class i should update two entities in the same transaction, for the ofher entity i already have the independent service that could the operation that i would need but it must be done in the same transaction, should i implement the unit of work pattern or is ok to use directly the dbcontext even for an operation that is already implemented separately? I hope it is clear. Thanks in advance.
@CodeOpinion
@CodeOpinion 5 месяцев назад
EF Core Context is a unit of work. Hence you can update multiple DbSets within the same transaction.
@alfonsdeda8912
@alfonsdeda8912 5 месяцев назад
@@CodeOpinion thank you for response, sorry, I have not mentioned one important thing,the relationship is one to many and I want to add an object in the many service, should I do all method to add those many objects in the one side service, because I have many relationship one to many with the same one entity, the one could be an aggregate but the one side service would be too big If I implement all many entities operations , any suggestion?
@snowglider400
@snowglider400 Год назад
@CodeOpinion why you didn't use state machine ?
@CodeOpinion
@CodeOpinion Год назад
Just an example. I have other videos where I do.
@SaudBako
@SaudBako 2 года назад
Instead of throwing exceptions on rule violations, is there any harm to make Shipment expose a single function, Advance(), which decides which stop to advance and how to advance (i.e. which Stop method to call) based on their states? If this over-simplified interface guarantees enforcing business rules, wouldn't these exceptions be unnecessary burden on Shipment consumers and tests?
@CodeOpinion
@CodeOpinion 2 года назад
No you absolutely could do that since there's a single progression. The issue is if you're in a concurrent environment where many different users could be trying to perform an action. You wouldn't want one to do Advance() at the same time as another. There you would obviously need to do some optimistic concurrency if you choose to go the Advance() route.
@danflemming3553
@danflemming3553 2 года назад
Even with the Shipment aggregate root, the PickupStop and DeliveryStop classes still have public methods which can change the statuses independently. How to solve this? Thanks!
@CodeOpinion
@CodeOpinion 2 года назад
If you want to go down the road of locking it down, use the appropriate access modifiers. TBH, I don't concern myself with it too much because the stops aren't directly accessible outside the aggregate. They are generally passed in via the constructor from a repository.
@danflemming3553
@danflemming3553 2 года назад
@@CodeOpinion Thanks but it's not that simple. Adding access modifiers means you won't be able to actually call methods on those classes. Maybe I am missing something, but it's not simple. Aggregate roots even with the latest EF Core is not simple to achieve if you really apply encapsulation and private access modifiers. Have you tried it?
@CodeOpinion
@CodeOpinion 2 года назад
@@danflemming3553 No I don't with EF. I distinguish between data models and domain models and I don't try to make both be the same thing. Generally I have an aggregate root that in the constructor takes in the appropriate data models. This aggregate root is built by a repository that gets the data models out to pass them in. So to have public setters on the data models (EF) is irrelevant because nothing besides within the aggregate root has access to those and it's the only thing making changes to the data (EF) models. I talk about this more in this video: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-GtWVGJp061A.html
@williamsbotchway2471
@williamsbotchway2471 Год назад
@@CodeOpinion I still have concerns with this. how is it possible to hydrate stops from a database with a respository. Repositories on only uses aggregate root not entities or aggregate for database rehydration. I am right? Pls advice.
@13odman
@13odman 5 месяцев назад
Didn’t you say that an anemic domain model is fine if you know it is?
@CodeOpinion
@CodeOpinion 5 месяцев назад
Absolutely. It has utility if you don't need a domain model and you realize that it's not a domain model.
@MsTArray
@MsTArray 2 года назад
isn't this somehow related to state machines?
@CodeOpinion
@CodeOpinion 2 года назад
The example is, yes.
@dayanshuwang2508
@dayanshuwang2508 2 года назад
Hey Derek, can you make these videos private and charge bit money? otherwise junior developers gonna catch up so quickly, we need our job to be safe 😂
@CodeOpinion
@CodeOpinion 2 года назад
Well we all learn various things at different points in our career path. Hoping some of the stuff I've run into along the way helps others regardless of where they are. Appreciate the comment!😊
@dayanshuwang2508
@dayanshuwang2508 2 года назад
engineers are naive, how many open source project geek cant even get fund or been turned down by big company that actually using their projects - the world is never fair and developers so easy to be taken advantage of since their logical and true/false thinking 😂 intellectual property/experience are easily copied or stolen, you have really reduced the learning path for junior jumping on a senior path which the older developers took a long way to arrive, mate 😂
@weraponpat1913
@weraponpat1913 2 года назад
why didn't i found this early so i don't have to refactor my code :(
@alvaromp1106
@alvaromp1106 2 года назад
The example is too complicated. It would have been better to pick up a simpler example to illustrate... I mean, after all the idea was to teach about aggregation right? Why make everything more confuse with deliveries, stops, shipment? Thanks anyway..
@CodeOpinion
@CodeOpinion 2 года назад
I also get comments that my examples are to simple. The challenge is finding the balance between complex enough examples that illustrate the need for certain design patterns and simple enough that the reader/watcher doesn't need deep understanding of the problem domain.
@yurimelo3404
@yurimelo3404 Год назад
I have a question about these three status: InTransit, Arrived and Departed. They are related to Pickup and also to Delivery, okay? I'll improve my question with an example to see if I understood it well. Let's say that I ordered a pizza at my house. So the order has been processed and the pizza is ready to be delivered to my house. So the food app has a delivery person responsible for delivering to my house, which, in turn, needs to go to the restaurant to pick up the food and then take it to my house. With this example there are several status changes. Which of the two scenarios is what the video is trying to say? Or is it another? (Note that I may have misunderstood.) First scenario: - Delivery guy going to the restaurant - Status changed to InTransit - Delivery guy took my food - Status changed to Arrived - Delivery guy left with my food - Status changed to Departed - Deliverer is on the way - Status changed to InTransit - Deliver arrived at destination - Status changed to Arrived - Delivery person successfully dropped off the food - Status changed to Departed Second scenario: - Delivery guy going to the restaurant - Status changed to InTransit - Delivery guy got my food - Status not changed [InTransit] - Delivery guy left with my food - Status not changed [InTransit] - Deliverer is on the way - Status not changed [InTransit] - Deliver arrived at destination - Status changed to Arrived - Delivery person successfully dropped off the food - Status changed to Departed
@CodeOpinion
@CodeOpinion Год назад
The first is correct.
@yurimelo3404
@yurimelo3404 Год назад
@@CodeOpinion Thank you!!! Your videos have changed my way of thinking about architecture by using Domain-Driven Design.
Далее
Highly COHESIVE Software Design to tame Complexity
9:01
БИМ БАМ БУМ💥
00:14
Просмотров 3,8 млн
Ne jamais regarder une fille à la plage 😂
00:10
Просмотров 766 тыс.
🛑 до конца!
00:12
Просмотров 86 тыс.
DDD is just giving a $h!t about your Domain
8:35
Просмотров 16 тыс.
My WORST Mistakes as a Software Developer
7:52
Просмотров 9 тыс.
Keep your project structure simple!
15:08
Просмотров 16 тыс.
Stop Calling Your API a "REST API"
17:42
Просмотров 16 тыс.
Domain Modeling Gone Wrong - Part 1
8:21
Просмотров 26 тыс.
Stop Using Records As Strongly Typed IDs!
10:15
Просмотров 9 тыс.
Do you need Domain Driven Design?
11:28
Просмотров 28 тыс.
НЕ БЕРУ APPLE VISION PRO!
0:37
Просмотров 375 тыс.
iPhone socket cleaning #Fixit
0:30
Просмотров 17 млн