Leaking Value Objects from your Domain

Ғылым және технология

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

Пікірлер: 45

  • @gpzim981
    @gpzim9812 жыл бұрын

    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.

  • @jarrodswords3729
    @jarrodswords37292 жыл бұрын

    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

    2 жыл бұрын

    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.

  • @sbeasley1120
    @sbeasley11202 жыл бұрын

    I really enjoy your content.

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Glad you enjoy it!

  • @user-fh3yh8mn4q
    @user-fh3yh8mn4q2 жыл бұрын

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

  • @cbaxtermusic
    @cbaxtermusic2 жыл бұрын

    Another golden video!!! Great stuff.

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Glad you enjoyed it!

  • @aaaarvil
    @aaaarvil2 жыл бұрын

    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.

  • @ricardo.fontanelli
    @ricardo.fontanelli2 жыл бұрын

    Great as always, thanks for sharing

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Thanks for watching!

  • @fredimachadonet
    @fredimachadonet2 жыл бұрын

    Thanks for your content!

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    Thanks for your support!

  • @ArtemKhodos
    @ArtemKhodos2 жыл бұрын

    Man, you are so undersubscribed!

  • @codiguard
    @codiguard2 жыл бұрын

    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

    2 жыл бұрын

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

  • @LuisdelCampo_guichosun
    @LuisdelCampo_guichosun2 жыл бұрын

    Excellent as always. Are DTO objects same thing?

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

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

  • @user-qt6tn4xl2e
    @user-qt6tn4xl2e2 жыл бұрын

    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

    2 жыл бұрын

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

  • @louisstekhoven-smith5791
    @louisstekhoven-smith57912 жыл бұрын

    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

    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.

  • @tomasjablonskis6053
    @tomasjablonskis60532 жыл бұрын

    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

    2 жыл бұрын

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

  • @marna_li
    @marna_li2 жыл бұрын

    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

    2 жыл бұрын

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

  • @marna_li

    @marna_li

    2 жыл бұрын

    @@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.

  • @chrismoutray9206
    @chrismoutray9206 Жыл бұрын

    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

    Жыл бұрын

    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
    @ToeShimmel2 жыл бұрын

    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

    2 жыл бұрын

    Records implement IEquatable and are equal by values.

  • @thedacian123
    @thedacian1232 жыл бұрын

    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!

  • @xavierlevaux621
    @xavierlevaux6212 жыл бұрын

    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.

  • @glennarens81
    @glennarens812 жыл бұрын

    Have you ever done a video about primitive obsession?

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

    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.

  • @MateuszNaKodach
    @MateuszNaKodach2 жыл бұрын

    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

    2 жыл бұрын

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

  • @MateuszNaKodach

    @MateuszNaKodach

    Жыл бұрын

    ​@@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

    Жыл бұрын

    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

    Жыл бұрын

    @@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

    Жыл бұрын

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

  • @syedib
    @syedib2 жыл бұрын

    Can we use record Type as Value Object ?

  • @CodeOpinion

    @CodeOpinion

    2 жыл бұрын

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

  • @craigmunday3707
    @craigmunday37072 жыл бұрын

    Seems like some Domain Value Objects are really Domain Primitives.

Келесі