I understand the concepts in DDD but in practise it gets a bit confusing.
I am using C#, SQL Server and EF. I see that based on my database schema, the persistence models would look different from my aggregates. In order to define clean, nice aggregates, entities and value objects, my domain models would look different from the database models.
Moreover, if I try to merge these 2 then somehow I try to design my domain models more based on technology, not on domain.
Maybe a more concrete example would be for example:
Do I need to add an ID field in the entity if that id is used just for DB?
In case of Many2Many relationships it can also get tricky
Are these 2 models different and the implementation of the repository must convert db model into domain model or I should make the domain models the same as the models used by EF?
A domain model describes the domain types that an organization allows and their constraints. Using domain data types instead of base data types ensures that you maintain consistency across an organization, and allows reuse of common data type definitions for greater team efficiency.
ER models are a kind of domain model. There are many other kinds, like network data models which are still very popular and often confused with ER models or object-oriented systems. Note that diagrams and models aren't the same thing - diagram are used to visualize models.
In practical purpose, domain and model are the same, while entity is also a domain/object that would be used to store in the database.
Each domain contains a set of data related to a specific purpose or function (data access, exceptions, policy violations, and so forth). For a description of all domains, see Domains. Each domain contains one or more entities. An entity is a set of related attributes, and an attribute is basically a field value.
That's a common issue when you start with DDD.
They are completely seperate things.
A Domain Model is an abstraction. It should not concern itself about the technology that you are using and it doesn't represent database tables, documents, classes, functions etc.
The Domain Model represents concepts, dependencies and interactions between these concepts.
Technology is used for the Implementation of a Domain Model.
Different technologies can be used to impelement the same Domain Model.
As much as we would like to have the freedom do do whatever we like with your domain models, in practice we do use a technology for it's implementation and sometimes this will affect it.
Of course you can dump all freameworks and libraries and make your own solutions that will make your implementation a lot easier. Even if you do this you are still left with your language, C#, Java, Rubi etc. and the tools that it provides you.
Here's an example:
Let's say we develop a system for can rentals. A person can rent a car. In our Domain we have the concept of an Account that a Person has, a Car
and a CarRental
.
Thats your Domain Model. At this point we are not concerned with the language, database or anything
Now to the Implementation of the Domain Model.
We will use C#. Now we need to decide for a database. If we decide to use SQL, we may decide to use the nice abilities of RDBMS to do joins so we may implement it by using integer IDs this way:
public class Account {
public int ID { get; private set; }
// other stuff
}
public class Car {
public int ID { get; private set; }
// other stuff
}
public class CarRental {
public int AccountID { get; private set; }
public int CarID { get; private set; }
// other stuff
}
On the other hand we may decide that integer ID's are not good because you can get collisions if you have to work with other systems and move databases and stuff, so we decide to think a bit and use an e-mail as a unique identifier for the Account and the licence place as a unique identifier for the Car:
public class Account {
public Email Email { get; private set; }
// other stuff
}
public class Car {
public LicencePlace LicencePlace { get; private set; }
// other stuff
}
public class CarRental {
public Email AccountEmail { get; private set; }
public LicencePlace CarLicencePlace { get; private set; }
// other stuff
}
If we follow DDD and devide your Entities into Aggregates properly, you should not need to do joins between them as they should not be loaded or changes in the same transation.
On the other hand, we may wan't to build a different model (read model maybe if we use CQRS, or we may need to extract reports) on top of the same database and using the second approach can make this harder since we loose the ability to do joins.
On the other hand, if we use a NoSQL database like MongoDB for example, we don't have the ability to do joins. So using integer ID's doesn't bring us any value.
Even if we decide use a SQL database and don't use integer ID's we can still use Domain Events and build additional models and reporting using them.
Also using joins won't work if we have a distributed system, so using integer ID's may not bring us any value at all.
Sometimes it's convinient to use the abilities of your technology to make some things easier, but we let it harm our Sytems and Domain Models.
We end up building system that are very robust from technological point of view but they don't do the things that they are supposed to do, and that makes them usesless.
A usesless system is useless no matter how good it's implemented.
If you haven't read the DDD book, read it. Eric Evans talks about how you technology can either help you or fight you all the way. Eric Evans also talks about how DDD allows for a freedom of implementation so that you don't have to fight your technology.
Another thing that we tend to do if think all the time about persistence. It's true that we persist things most of the time but that doesn't mean that a Domain Model is something that is Persisted to a database.
When I started programming, I started with computer graphics and modeling applications like 3DsMax and Maya. When I started to write applications that use the holly Database it was really weird to me how people don't think and don't know about their domains, just persist stuff and make them work and all they talk about is technology.
If you are into computer graphics you won't be able to write a single like of code if you don't know Math. So you start with learning Math. After you know some of it, then you can write code.
Let's take games for example. You may design a Physics Engine that models the Domain of physics . In this model you will have concepts like Work, Power, Gravity, Acceleration etc. It's not necessary to persist them. You do persist other conceps like Weight of your Player for example so that the Physics Engine will know how gravity should affect it, but still you don't persist Power to the database. It's still a Domain Model. Power, Workd etc are functions, not entities of aggregates. They are still part of your Domain Model.
Let's say you wan't to build a Physics engine The thing is that if you wan't to build a Physics Engine you have to know Physics. Physics is complex. Even if you are a really good programming knowing in EF or SQL of whatever, it won't help you build Physics engines. Knowing the Domain of physics and being able to make a Domain Model of it and then Implement it is the key.
If you want to really feel the difference between a Domain model from Implementation, check this out, This domain can blow your mind before you get to any implementation.
Also check this article on modeling entities with DDD.
EDIT
Here is another article that explains differences between NHibernaty and EntityFramework for Domain Modeling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With