Your Domain Model isn't your Data Model

preview_player
Показать описание
If you're using an ORM and creating "domain entities" you're likely trying to force your database structure into your domain model. That can work but the point of persistence ignorance is to let you domain model shine without knowing how it's persisted. But you're data structure will force you down a certain path if you treat your data model as your domain model.

🔗 EventStoreDB

💥 Join this channel to get access to a private Discord Server and any source code in my videos.

🔥 Join via Patreon

✔️ Join via YouTube

0:00 Example 1
2:04 Data Only Properties
3:43 Domain Model != Data Model
4:41 Separation
5:36 Data is in the Domain
Рекомендации по теме
Комментарии
Автор

This video is so freaking good. A prime example why CodeOpinion is my undisputed favorite YT channel for software architecture and design.

majormartintibor
Автор

In my experience, a set of parallel "model" and "entity" classes aren't even the worst of the problem.

I'm a Java developer, but I expect this happens in C# code too: copying everything back to the ORM-managed objects breaks the automatic change-detection logic, you don't always need every field so someone reimplements lazy loading, someone else realizes that you need a way to specify what to load from the database so they reinvent a "criteria" mechanism, you've doubled your memory usage by having "model" and "entity" copies of everything, and someone who is unaware of the first- and second-level Hibernate caches adds another cache at the "model" layer. I've seen these issues across multiple projects.

I've also seen projects that use JDBC to talk directly to the database instead of using an ORM, and you must have at least one person who knows JDBC and SQL really well for that to turn out okay. I think people generally understand that, but I believe that it's the same if you use an ORM. You still need at least one person who knows the ins and outs of SQL and the ORM really well, to make sure that you're not shooting yourself in the foot. So why bother? Because it can result in less code and better performance with less effort.

To be clear, I don't believe that an ORM is always the right approach. But if you use an ORM, think of it as a commitment rather than an easy way out or it's going to come back to bite you.

sambishop
Автор

Persistence Ignorance is one of those patterns that have caused much more problems than it ever solved. Adhering to REST is probably the worst example.

gunnarliljas
Автор

This has to be one of the most influential YT vids on SA I’ve watched in a while.

Your take on passing the infrastructure to the domain is great and seems pragmatic.

I will say though that using some micro ORMs like JOOQ for getting the aggregate in a handcrafted query and mapping that to the domain can also be great if you want to have a “cleaner” domain. I wouldn’t recommend that with an ORM though!

Great vid! Keep it up

EvomanPl
Автор

Using ORM is the problem, or at least the reason for this whole confusion.

Say you use Dapper and you write the SQL yourself.
If you persist - you just give your domain model to the repository, its job is to know how to persist it, the application layer doesn't care where it's persisted, which table/tables are involved etc.
If you query - you define the view model, with types, formatting, property names exactly how you need them for the case, the repository's responsibility is to prepare it for you, the application layer doesn't care how.
And you always have great flexibility, total control over the SQL.

But you decided to use some opinionated, limited, magical ORM, because "writing SQL takes so much time".

iliyan-kulishev
Автор

Domain models aren't the data model, but I would argue the identity of the object belongs to the domain. You can't expose meaningful behavior if you can't specify what model to operate on. In my experience, it's always been best to isolate the data models in such a way that you simply pass your domain models to that layer and let it be entirely responsible for mapping back and forth between whatever persistence backend you're using. This allows you to change that backend entirely independently of the rest of the system. If you're worried about mapping overhead, don't use an ORM on top of this.

kaizer-
Автор

Yet to see a fully decoupled domain, data model where the promises of doing that are actually needed, and I've been doing this for around 10 yrs

void_star_void
Автор

While the Shipment may not need the Shipment Id. Debugging is a hell of a lot easier when it does have it. Fair enough, drop the other fields.

MrMikeJJ
Автор

Hello, thanks for your contents. I really appreciate your videos. However, I didnt understand the point here, when you advocate against the use of ID. I mean, by definition, all DDD books I have read says that the main characteristic of an entity is that it has an identity. Even further, Vaugh Vernon in DDD red book make use of and ID as a value object, in order to encapuslates ID details. Please, dont take me wrong, I really want to hear your toughts about my point of viewing. Your videos always give me good insights. Thanks again.

betopolione.laura.gil.
Автор

I also think that some people forget that actually, outside of a database, your domain does have persistence, and always will have. Whether you recorded transactions in a book before, give your clients a reference number, that’s an ID in itself, composite keys if you need to, I have used domain entities for a while now, I get them as valid as possible, and when I think about ‘mapping’ to the database, I see that as your setup (in my cases using fluent api on entitytypeconfiguration). I really enjoyed this video, we have a laugh a chap and I at work, he’s so against having the entity anywhere near the database and I’m such an advocate for it!

jamesthompson
Автор

Would be nice to have a written version of this video for better analyzing

itmarck
Автор

Derek, do you have a small repository with sample code which shows this idea? Thanks!

danflemming
Автор

Hey there :) thank you for this content. I had to replay this video a bunch of times (part of it because i'm not a native english speaker) to make sure I understood it well :

- 1 : The domain does not have to deal with every part of your persisted data model, if no business logic gravitates around it.
- 2 : Doing this separation can be hard, it really depends on the how clean you want your modeling to be. Having a 100% mapping coverage between your persisted data model and your domain data model is not an ultimate goal, and can sometimes be overkill and harmful for a given project / team / situation.
- 3 : 4:42 : you propose to pass only a part of the persisted data model instance to your domain model (this seems wrong to me, as no mapping to a "domain-allowed" type is performed, but maybe that was not your point). Is it a clean or dirty solution ?
- 4 : 5:53 : you say it's against clean architecture (i agree, because no mapping of the data coming from the infrastructure has been done to represent a domain entity : am I wrong ?)
- 5 : 5:58 : you say it's not a problem... and at that point i'm bit lost... Do you mean it's ok to have business data in the domain, as long as this data has business value for the end user, even if no logic (methods of the domain) uses that piece of data to "take decisions" in the business processes ? (like an order ID or tracking ID accessible to the end user)

Can anyone having a clear understanding of what have been said, can help me pointing out on which of those 5 listed takes I may have missed something ? or confirm if i'm on the right track ?

Thanks in advance to anyone helping me to understand this well.

ElPayetSUPERVAN
Автор

What happens now when you need to persist the stops back in the repository? Does the domain model need to expose those data objects with getters?

bikeaday
Автор

Nice video! How do we ensure that some parts of our data only changes if we do it using the aggregate ? Because in our domain we might have for example a domain model that has some properties that in order to be changed some domain validation has to occur and for some other properties we might only need crud operations. That's my main concern ensuring that the data is only modified if it was from the domain model.
Another question i got is that for example we got a category and that category can have a parent in case we want to move a category from one parent and we might have to apply some domain related logic to it so we would handle this domain logic from a category manager that applies the domain logic to the categories data model or the category manager would interact with the domain models and tell them what to do ?

Felipe-av
Автор

I appreciate this video, but sorry I’m still confused. I wish there was a good real-life example out there that shows more than just the basic examples usually shown.

tibba
Автор

I wish you also have some practical solutions to the problem which is a very known problem.

danflemming
Автор

I believe most of the pain comes from the fact that people map (public) properties to columns. In JPA for example you can choose between property and field access. If you use latter you can provide custom properties and behaviour, as your data is not visible to everyone. In EF the same should be achievable with backing fields.

wbiller
Автор

Derek, I can understand the line of thought of having separated Domain and Persistence models, even having ORMs in place, but what do you think about the additional overhead of "converting" in and out between domain and persistence classes? And about the decision of some developers of doing this using mapper tools?

MrBlackWolfX
Автор

ID isn't really a persistence-level concern, it can be thought of as very much a domain construct. That was not a good example to make your point IMO, although the video was interesting.

amirhosseinahmadi