milandjukic88
milandjukic88

Reputation: 1115

I'm confused how to update Entity in Domain Driven Design

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"):

  1. User sends command.
  2. Application service gets domain model
  3. Then application service calls repository to persists that model
  4. Repository (infrastrucure layer) translates that domain model to his DB model and write to DB

Second scenario (I want to update "concert")

  1. User send command to update concert
  2. Application service calls repository to get "concert" to update (first question what repository should return here, doest it need to return domain model or something else)
  3. Now (if I have domain model) I can call method concert.sellTickets(3);
  4. Then app service calls repository to update that concert

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

Answers (1)

desertech
desertech

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

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

Related Questions