What makes an Aggregate (DDD)? Hint: it's NOT hierarchy & relationships

Поделиться
HTML-код
  • Опубликовано: 26 июл 2024
  • How do you design an aggregate in domain-driven design? An aggregate in a cluster of related objects and used to manage the complexity of business rules and data consistency. Designing aggregates often incorrectly because of the focus on the relationship between entities.
    🔗 EventStoreDB
    eventsto.re/codeopinion
    🔔 Subscribe: / @codeopinion
    💥 Join this channel to get access to a private Discord Server and any source code in my videos.
    🔥 Join via Patreon
    / codeopinion
    ✔️ Join via RUclips
    / @codeopinion
    📝 Blog: codeopinion.com
    👋 Twitter: / codeopinion
    ✨ LinkedIn: / dcomartin
    📧 Weekly Updates: mailchi.mp/63c7a0b3ff38/codeo...
    0:00 Relationships
    2:05 Aggregate
    5:12 Invariants
    6:00 CQRS
    #domaindrivendesign #softwaredesign #softwarearchitecture
  • НаукаНаука

Комментарии • 44

  • @wertrager
    @wertrager Год назад

    Thanks, I've been wondering about this for years, finally you made it clear to me why an aggregate should only be used for state change and not for queries.

  • @appstratum9747
    @appstratum9747 Год назад +1

    Great introductory video to this aspect of DDD. Primarily because it's thought provoking and this is an important topic that needs thoughts provoked!😀
    This is the kind of video that fosters the sharing of wisdom rather than merely knowledge. And for that you deserve a lot of credit. This sort of material will be invaluable to so many careers and will really raise the bar for so many once they grasp what you're sharing with them.
    Having said that, we're just scratching the surface here and I think this video needs (and deserves!) a follow-up of similar length using the same example but to a slightly greater depth (yet still introductory... linking on to other videos you've made related to this). Or episodes 2 (commands) and 3 (queries) of a three-parter with similar linking into related material. I think would help a lot of people start to get over this significant mental hurdle and start to get to grips with seeing the "Big Picture" of this important aspect of DDD.
    I know you've covered all of this elsewhere in some form, but perhaps not coming at it from quite this angle of hierarchy & relationships. Or at least not with quite the same sharp focus on this topic from this perspective that you've achieved here.
    Great video, though - as usual. 🙂 And many thanks for posting this. Good work, fella!

    • @CodeOpinion
      @CodeOpinion  Год назад +1

      Thanks for the comment. Ya, some of these I need to do follow up videos that keep going more in depth. Agree.

  • @retrodad9390
    @retrodad9390 Год назад +1

    As always, good video! And the most difficult subject there is.

  • @romanlunin386
    @romanlunin386 Год назад

    Thanks for the video! Top notch content, as usual.

  • @dropbeardan9604
    @dropbeardan9604 Год назад +10

    This is great, I definitely dug myself into that hole when I started off and wished that I had this as a resource back then.

    • @CodeOpinion
      @CodeOpinion  Год назад +3

      Ya, most of us learn the hard way.

    • @user-du6vx7ir7m
      @user-du6vx7ir7m 7 дней назад

      @@CodeOpinionlol in it now ordered ugx max (300?) the 16 port SE 8poe+ switch, tplink 1gb switch, protectli vault fw 8gb, UAP 6pro (solid) a UAP 6+ (solid), poe injector, USBs out the ass ethernet cat 6 out the ass a raspberry pi cannakit for a dns i am not risking self hosting and opnsense config’d that took 8 hrs and needs reconfiguring again bc unifi controller was config’d and both have to match, IT ppl preset vlans😢 udm pro and cloud key otw :/ possible usw pro 24 too jfc

  • @GilbertoMadeira83
    @GilbertoMadeira83 Год назад +1

    Hi Derek, your videos are the best!

  • @ismailbayram_ce
    @ismailbayram_ce Год назад

    thank you for the content.
    A classic aggregate example: Order in an e-commerce system, which includes basket, basket items with its prices and so on. But I didn't a comprehensive example project written in golang. Most of all contains basic structure

    • @CodeOpinion
      @CodeOpinion  Год назад +1

      Ya. So a good example of why you might consider using an aggregate in that situation is let's say you persisted the tax amount on the basket itself. That would need to be consistent with the line items (total) of the order.

  • @ZadakLeader
    @ZadakLeader Год назад

    Sup Derek, like i mentioned in the last video, you might want to invest in a DSLR because the video looks blurry :)
    Good content!

  • @yonatandaniyel5640
    @yonatandaniyel5640 3 месяца назад

    Good explanation about CQRS here.

  • @MrDomenic123
    @MrDomenic123 Год назад +3

    Another piece of gold, thanks a lot for this great content, Derek! I got one question though (not directly related to your video):
    Let's say you have two services (Service A and Service B). Both services are in their corresponding boundaries. Both services are aware of the same aggregate (e.g. Order) but with different attributes/properties. However, both services need the same property from the client to perform some type of calculation. Let's call that property "P". Each service needs the property P to calculate other values that are used for validation, let's call the calculated value C. So, the property P is just used to calculate C. Now, what if both services (Service A and Service B) have to perform the exact same calculation to resolve the property P to the calculated value C?
    Is it better to have a dedicated service (e,g, Service C) that calculates the value of the property C for each aggregate, and publishes that via an event, or should the calculation logic be "duplicated" among both services in the first place (Service A and Service B)?

    • @CodeOpinion
      @CodeOpinion  Год назад +1

      Both services don't have the "same" aggregate, they have the same underlying concept of an Order. To answer the question, can one have the value eventually consistent? If so, then it's not the point of truth, the one that is is that needs consistency.

  • @user-jq8tc2oj7t
    @user-jq8tc2oj7t Год назад

    Thanks for the video! Good stuff as always. Did you by any chance read the "Kill The Aggregate" blog series by Sara Pellegrini? A video with your take on that would be awesome!

    • @CodeOpinion
      @CodeOpinion  Год назад

      I'm aware of it. I'll check it out. Good suggestion!

  • @thomasjardanedeoliveirabou9993
    @thomasjardanedeoliveirabou9993 10 месяцев назад

    I don't get how you keep consistency between the location an vending machine, how do you enforce that each location can only have one vending machine with this method? Or for example, if I already have an registered vending machine that I want to place it in a location, how do I enforce that invariant across boundaries?

  • @roeiohayon4501
    @roeiohayon4501 Год назад

    Lets say i am trying to model the problem of doing some business operations on historical stock data, so a stock is basically a symbol (for example AMZN), and a time series that represents the data of that stock. Often we want to query and do operations on the stock data based on symbols, so ultimately my question is, should symbol also be an aggregate root, alongside with stock? If not, should i still have two separate repositories? If so, should I create a repository that encapsulates both of them? How would you go about handling this situation of nested aggregate?

    • @CodeOpinion
      @CodeOpinion  Год назад

      This sounds like a query concerned and nothing to do with an aggregate. Check out: ruclips.net/video/hQVisFBAQio/видео.html

  • @quilhon7644
    @quilhon7644 Год назад

    This is really a more resanble way to design the software.

  • @flobuilds
    @flobuilds Год назад

    How do aggregates work in a scenario where you have one entity which has many different lists of other sub entities and these may also have lists. So in highly nested entities. Could you set the aggregatr root on different entities that may be nested but need different domain events or something like that?

    • @CodeOpinion
      @CodeOpinion  Год назад +1

      This is my point. The one to many, nested hierarchy isn't the purpose of creating an aggregate.

    • @flobuilds
      @flobuilds Год назад

      @@CodeOpinion thank you so much that's what i needed. So the aggregate is just there to handle the entity and maybe also if present the sub entities in lists or just connected entities and value objects and this makes it easier to set domain events on highly nested entities. The interceptor will just Catch all aggregate roots and use do something to the events

    • @CodeOpinion
      @CodeOpinion  Год назад +1

      Check out this video, it might clear it up more: ruclips.net/video/64ngP-aUYPc/видео.html

    • @LeviRamsey
      @LeviRamsey Год назад +3

      There's no reason you couldn't do that, but the key thing to remember is that updates to those sub-entities have to appear to happen in sequence (in DB terms: strict serializability... you tend to get strict serializability for free with event-sourcing (e.g. EventStore, Akka...)): there's going to be some form of concurrency control (could be optimistic or pessimistic) around the entire aggregate and that concurrency control will tend to place substantial limits on scalability and/or performance.
      Thus, I advocate thinking about the operations (as a supertype of commands and queries) and which operations should have a guarantee that they see the results of (thus happen after) which other operations: if operation A needs such a guarantee with respect to operation B, then that's a definite sign that operation A and operation B both need to be performed on the write model (even if one of them is a query; note that at least one of them must be a command in order for "see the results of" to be meaningful) and a strong sign that operation A and operation B touch the same instance of the same aggregate. Teasing out where you need strict serializability leads you to aggregates that are "sized just right": large enough so that you get the consistency guarantees you need but not too large that you're fighting a losing battle against scalability/resilience/cost.

    • @flobuilds
      @flobuilds Год назад

      @@CodeOpinion thank you so much this really helps me understand these concepts better

  • @AndersBaumann
    @AndersBaumann 4 месяца назад

    I agree on the idea of the video but publishing an event to make a change in another aggregate is adding complexity instead of removing it. This kind of hidden side effect will make the codebase difficult to understand, test and maintain. To me it is a misunderstanding of what domain events are for: To notify the outside world (outside the bounded context) of state changes.

  • @botyironcastle
    @botyironcastle 2 месяца назад

    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?

  • @ZadakLeader
    @ZadakLeader Год назад

    I guess in the end an Aggregate is just simplifying the operations between simpler concepts like a route or a vending machine? That's how I see it

    • @CodeOpinion
      @CodeOpinion  Год назад +2

      The point is having a root that manages all the entities/value objects in the aggregate (cluster). Often because other objects in the cluster care about the operation being performed. Without the root, they would have no way of knowing unless you used events. Or the operation requires more that one entity to be changed and you require consistency throughout the entire aggregate when persisted.

  • @thedacian123
    @thedacian123 Год назад

    What if vencing machine can't exists without the Route object.I mean between Route and Vencineg is a composition relation.?Won't be forced to include int he same aggregate(object) all the objects cluester?Thank you!

    • @CodeOpinion
      @CodeOpinion  Год назад +1

      As mentioned I think in one portion, depending on how your persisting this, it can also be done at the DB level.

  • @emonymph6911
    @emonymph6911 Год назад

    Can you please make a video on possible event driven SSR tech stacks with JS SSR frontend framework and python backend for those sweet lib imports, but a data stream to make it all real time because both JS and python are slow. if that is even possible.
    My idea is this. Frontend SveltKit for the UI and capturing a users event. Then an event stream like Kafka listens to the event and takes it into the DB or Backend (not the event stream passes to DB or backend first or can do both). I'm assuming you can use an easy language which on its own is slow like Python to control the faster tools a message stream. Then you don't have to worry about speed. You can also use python libs to wrangle the data from your DB afterwards and who knows maybe pass the object it creates like a chart back to the frontend svelte UI via the message broker? Or is the message broker only one way? Ahh devops is so confusing! Or do you have to use a web component if you want to have a non-JS backend like python or Go, but can the web component even be SSR?

  • @ghevisartor6005
    @ghevisartor6005 8 месяцев назад

    ok noob question time, i'm trying to watch this and other of your videos to see if i can put together all the pieces. It seems to me that Aggregates are basically modelling business processes.
    If i have an ecommerce and i give the user a settings page to add products definitions to the catalog, aggregates are not really needed. Sure there is a "dummy" business rule that the price cannot be below zero, but it's a simple validation on a crud operation.
    When instead users place an order, a whole process is spawned and we need to make sure it will go trough respecting the invariances, aka the real business rules, in which case an order places cannot be have a total below zero but it's a different story then doing crud validation like before, we have to check the quantities etc etc.
    But then i see the Amichai example you reviewed in another video and i fail to see where aggregates can be usefull, where the business processes are. The user make a reservation for a dinner and that's it? now the next user might not be able to make the same reservation and he will need to choose another date, but it's not like we have to send notifications to the kitchen or other deparments to get ready for the dinner. Sorry i'm might getting confused here.

    • @CodeOpinion
      @CodeOpinion  8 месяцев назад

      You're on the money, they relate to business processes. Check out this video that might illustrate it better: ruclips.net/video/64ngP-aUYPc/видео.html

  • @emonymph6911
    @emonymph6911 Год назад

    A beginners video on how to get into API design would be neat. ^.^

  • @slobodanmikaric2180
    @slobodanmikaric2180 Год назад

    good example how designing bounded context went wrong.

  • @BraBo
    @BraBo 10 месяцев назад

    Everyone is doing DDD Aggregates the wrong way!!!
    ... it's actually impressive!

    • @BraBo
      @BraBo 10 месяцев назад

      "An Aggregate is a cluster of associated objects that we treat as an unit for the purpose of data changes.
      Each Aggregate has a root and a boundary.
      The Boundary defines what is inside the Aggregate.
      The root is a single, specific Entity contained in the Aggregate."
      By Eric Evans
      "Contained" is the key word here!
      An Aggregate is not a root, and is not an Entity!

    • @BraBo
      @BraBo 10 месяцев назад

      ... and as a final note!
      An Entity could be the root object in one Aggregate, but not in another!!!