Reputation: 1115
I'm learning DDD and have some troubles. I've created rich domain model with value objects and some functions for manipulating model properties. Currently i'm using in memory DB and my domain models are persisted as is. All is good. But now i want to separate domain model from DB model.
Scenario for creating (lets say "concert"):
Second scenario (I want to update "concert")
concert.sellTickets(3);
Does my thinking is good?
Does repository need to reconstruct DB model to Domain model and return to caller?
I hope you understand what I'm asking.
Above scenarios with some sample code:
Creating concert (application layer)
// application service
var concert = Concert.Create(); // creating rich domain model or concert
_repository.Add(concert);
Update concert (sell tickets) - application layer
var concert = _repository.Get(//by id); // this is rich domain model
concert.SellTickets(//some number); // calling "smart" method
_repository.Update(concert); // persisting to DB with new value
repository side (writing) (infrastructure layer)
var concert = Adapter.Map(domain_model); // converting rich domain model to plain class for pesisting
_db.Add(concert);
_db.SaveChanges();
repository side (reading) - infrastructure layer
var concert = _db.Find(); // read concert from db
var rich_domain_model = Adapter.Map(concert) // convert it to rich domain model
return rich_domain_model;
I know that ORM's using their mappers, but let's say I'm using,for now, in memory DB. So i need to do some conversions.
Upvotes: 4
Views: 5416
Reputation: 1029
These two use-cases you are presenting are pretty standard in the context of DDD world. Also, they reflect a valid separation between domain model (domain layer) and database model (infrastructure layer).
- Application service gets domain model
What do you mean by "gets"? A command object received by user is a flat object, containing no value objects; it is not (and should not be) a domain model. It is possible to delegate command-to-domain translation to application service, however some would prefer to apply such translation inside API layer (it is a matter of taste).
User send command to update concert
There are probably more than one command that "update" a concert (e.g. assign musicians, order hall, selling tickets). This is why we should be careful when defining a single update operation in the context of DDD: sending a command with many properties not necessarily relating to each other is a symptom of an anemic model.
first question what repository should return here, does it need to return domain model or something else
A repository should translate database objects into a domain entity, and return the latter. In DDD all layers "know" the domain.
One last point:
A rich domain is more than entities with value objects and methods that manipulate properties; the richness should be expressed by "smart" methods, that is methods that perform appropriate validations to prevent the entity from entering an inconsistent state. If you want to project a domain model as is into database, there is no point for smart entities because running plain validations would be sufficient. But if your application is not purely CRUD, providing rich flows and structured as many user commands mutating business entities, that's where DDD shines.
Upvotes: 3