Leaking Value Objects from your Domain

Sdílet
Vložit
  • čas přidán 19. 06. 2024
  • Value Objects are a great way to explicitly capture concepts within your domain. Value Objects are immutable, always in a valid state, provide behavior, and are defined by their value. This sounds a lot like Messages (Commands, Events) that are also immutable and should be in a valid state. However, exposing your Value Objects by using them within Commands or Events can have a negative impact on your ability to evolve your domain model.
    🔗 EventStoreDB
    eventsto.re/codeopinion
    🔔 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
    0:47 Value Objects
    2:11 Examples
    4:07 Leaking Value Objects in Messages
    #softwarearchitecture #softwaredesign #ddd
  • Věda a technologie

Komentáře • 45

  • @gpzim981
    @gpzim981 Před 2 lety +5

    Fantastic. Love content about defining what things are, what they are for and specially what they are NOT for, like value objects as a way of exchanging data across boundaries.

  • @sbeasley1120
    @sbeasley1120 Před 2 lety +7

    I really enjoy your content.

  • @user-fh3yh8mn4q
    @user-fh3yh8mn4q Před 2 lety

    めっちゃわかりやすい!
    いつも参考になります!
    bounded contextの中と外をしっかり意識する必要があるんですね。

  • @jarrodswords3729
    @jarrodswords3729 Před 2 lety +1

    I've literally been struggling with this concept for the last few days. It seems so natural to allow a message to contain a value object if you think of a message as a domain-level concept. But that would come with the catch of each context needing to have its own representation of the message itself b/c of the leak you described. Thanks!

    • @CodeOpinion
      @CodeOpinion  Před 2 lety

      Correct. Some core domain concepts can be pretty stable, but I'm still in favor of having messages be contracts that you version and aren't affected by your domain model changing.

  • @aaaarvil
    @aaaarvil Před 2 lety +1

    I learned the hard way of not putting value objects in events, just a small change on the value object caused subscribing services to send out corrupted events. Good thing it's not in production.

  • @cbaxtermusic
    @cbaxtermusic Před 2 lety

    Another golden video!!! Great stuff.

  • @ricardo.fontanelli
    @ricardo.fontanelli Před 2 lety

    Great as always, thanks for sharing

  • @fredimachadonet
    @fredimachadonet Před 2 lety

    Thanks for your content!

  • @codiguard
    @codiguard Před 2 lety

    Great video, thanks! I remember that in one of the older videos you were talking about book/course about properly architectured monolith, is this already available?

    • @CodeOpinion
      @CodeOpinion  Před 2 lety +2

      Not yet! But I'll be posting on here when it's available.

  • @ArtemKhodos
    @ArtemKhodos Před 2 lety

    Man, you are so undersubscribed!

  • @LuisdelCampo_guichosun

    Excellent as always. Are DTO objects same thing?

    • @CodeOpinion
      @CodeOpinion  Před 2 lety

      No. DTO are simply for transferring and serializing between layers or boundaries. DTOs should be treated as contracts.

  • @user-qt6tn4xl2e
    @user-qt6tn4xl2e Před 2 lety

    Thx for the video! What do you think about using value objects for each primitive except bools and dates? When is it useless? And What about events for event sourcing or other events within service boundary kind of “internal” events, is it good to use value objects there?

    • @CodeOpinion
      @CodeOpinion  Před 2 lety

      Domain Events or Integration Events are a topic I'll cover in a future video!

  • @louisstekhoven-smith5791
    @louisstekhoven-smith5791 Před 2 lety +1

    What about DTO's?
    I have some data a repository needs to get from the DB, however it is stored as a json string.
    Should we do some work in the repository and have it return a more useful dto, or just get the json and do the mapping in the application service layer?
    Either way I don't feel like we are leaking the domain.

    • @CodeOpinion
      @CodeOpinion  Před 2 lety +2

      You just don't want to expose anything outside your boundary or cross an integration boundary. Messages, and DTOs, HTTP responses are all used for crossing a boundary. You want them to be stable.

  • @marna_li
    @marna_li Před 2 lety

    Great point! Since I started to think about how I write code, I also have started to separate my domain objects from the DTOs.
    By the way, what is your opinion on JSON Patch? And what are the pros and cons? To me it does not seem like it is not applicable when not mapping resources to domain objects - for example in a behavior-centric API.

    • @CodeOpinion
      @CodeOpinion  Před 2 lety

      I don't every really use PATCH to be honest.

    • @marna_li
      @marna_li Před 2 lety

      @@CodeOpinion OK. I don’t see a use for it since I want to center around behaviors.
      Using HAL and HAL-Forms to format data and to describe my actions.

  • @tomasjablonskis6053
    @tomasjablonskis6053 Před 2 lety

    It would be interesting to see how authorisation and authentication is handled in DDD based system. Is the logic (services/commands/etc.) separated into its own Bounded Context? If so how is access control handled in other Bounded Context? Is crossing the boundary between BCs every time we need to check permissions that live in Identity & Access BC a problem? Is authorisation and authentication even a Domain concern?

    • @CodeOpinion
      @CodeOpinion  Před 2 lety

      Ya it's a topic I'll definitely cover in a future video.

  • @chrismoutray9206
    @chrismoutray9206 Před rokem

    I like this, but now thinking...What about string properties that don't have any business rules expect that they must be set; would you continue with methods to enforce this or explicit value object type for each or maybe a more generic type like 'NotNullString'. - great content, keep it up :)

    • @CodeOpinion
      @CodeOpinion  Před rokem +1

      Often, strings alone aren't a thing really. They are usually with something else that creates an entity or even value object. If it's just a string that's a property, and it's simple CRUD, then let it be CRUD with trivial preconditions before setting.

  • @ToeShimmel
    @ToeShimmel Před 2 lety

    I'm pretty new to c# but why are you using a "record" type instead of "struct"? Is it because record has built in serialization? Thanks

    • @CodeOpinion
      @CodeOpinion  Před 2 lety

      Records implement IEquatable and are equal by values.

  • @thedacian123
    @thedacian123 Před 2 lety

    Hello.What will happend if a user makes a type when entering an address, does 'it worth to make Address immutable,I mean each time the user changes an address we will recreate another value object right? Thank you!

  • @syedib
    @syedib Před 2 lety

    Can we use record Type as Value Object ?

    • @CodeOpinion
      @CodeOpinion  Před 2 lety

      Yes but there's some limitations as they are right now.

  • @glennarens81
    @glennarens81 Před 2 lety

    Have you ever done a video about primitive obsession?

    • @CodeOpinion
      @CodeOpinion  Před 2 lety

      No I haven't. Most often how I hear/read the argument against primitives is because of having method signatures that are easy to pass in incorrectly. Eg DoWork(int, int, int). I can't say I think this is the reason why you should create explicit types. But rather it's to do exactly that, be explicit about the concepts in your domain. I'll cover it a different way in the future, but I suspect most think of "primitive obsession" about method signatures and I think about it as defining concepts.

  • @xavierlevaux621
    @xavierlevaux621 Před 2 lety +2

    Don’t make your domain leak outside your bounded context.
    The objects you use to communicate with the outside are contracts. You don’t want to couple your domain in a contract with the outside. It would make your domain unable to freely evolve.

  • @MateuszNaKodach
    @MateuszNaKodach Před 2 lety

    What about DomainEvent? Would you place ValueObjects inside them?
    What I mean is for example a functional approach, where you have method like decide with declaration like this:
    ```List decide(List previousEvents, Command command)```
    In such case, decide is your domain logic. DomainEvents are, of course, parts of the domain.
    It's strange to accept as input to domain / return from domain primitives instead of ValueObjects.
    Or would you create Domain and Application layer representation of each Event and Command and then map between them when necessary?

    • @CodeOpinion
      @CodeOpinion  Před 2 lety

      Depends if you're exposing Domain Events outside of your own boundary. If you are, then no.

    • @MateuszNaKodach
      @MateuszNaKodach Před rokem

      ​@@CodeOpinion I've found my comment from year ago :D But I have similar thoughts, still. So the answer is: no. I don't expose Domain Events outside the boundary. I've just used them inside and for possible Event Sourcing. They are not serivce contract - for that I make another events (more coarse-grained) like IntegrationEvent.

    • @CodeOpinion
      @CodeOpinion  Před rokem

      The answer isn't a hard no. It depends on how stable the business concept is. If it's not something technical that is likely to change but rather a stable business concept that's core to the domain, then likely you can with some consideration

    • @MateuszNaKodach
      @MateuszNaKodach Před rokem

      @@CodeOpinion Thanks for the answer, faster than mine :) OK, what do you mean by "consideration"? If it's not stable I assume that I may have a problems with versioning, also with Events used for Event Sourcing. So, what about solution that I may have 3 repesentation of events: 1. Domain Event -> created inside aggregate, with ValueObjects, part of the domain.
      2. Stored Event -> used for Event Sourcing, without Value Objects. In case of some changes I may make upcasting from this event to Domain Event, so aggregate is only aware of the event from 1 point.
      3. Integration Events - for outside boundary communication, of course without any Domain references.
      It's just strange for me not to use ValueObjects inside Domain Events if Domain Events is as name stated "Domain" conecpt and created inside aggregate. If do not place VOs inside Domain Events I need to "unwrap" VOs to primitives inside the core of the domain.

    • @CodeOpinion
      @CodeOpinion  Před rokem +1

      All made sense. Why not use VO in domain event? You could. Often times however domain events are pretty slim if used for notifications

  • @craigmunday3707
    @craigmunday3707 Před 2 lety

    Seems like some Domain Value Objects are really Domain Primitives.