Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to model an entity's current status in DDD

I am trying to get to grips with the ideas behind DDD and apply them to a pet project we have, and I am having some questions that I hope that someone here would be able to answer.

The project is a document management system. The particular problem we have regards two notions that our system handles: That of a Document and that of a DocumentStatus.

A Document has a number of properties (such as title, author, etc). Users can change any of the Document's properties through out its life time.

A Document may be, at any time, be at a particular state such as NEW, UNDER_REVISION, REVISED, APPROVED etc. For each state we need to know who made that change to that state.

We need to be able to query the system based on a document status. An example query would be "Get me all documents that are in the REVISED state".

"Get me all documents whose status has been changed by user X"

The only time that a Document and a DocumentStatus need to be changed in the same transaction is when the Document is created (create the document and at the same time assign it a status of NEW).

For all other times, the UI allows the update of either but not both (i.e. you may change a document's property such as the author, but not its state.) Or you can update its state (from NEW to UNDER_REVISION) but not its properties.

I think we are safe to consider that a Document is an Entity and an Aggregate Root.

We are buffled about what DocumentStatus is. One option is to make it a Value Object part of the Document's aggregate.

The other option is to make it an Entity and be the root of its own aggregate.

We would also liked to mention that we considered CQRS as described in various DDD documents, but we think it is too much of a hassle, especially given the fact that we need to perform queries on the DocumentStatus.

Any pointers or ideas would be welcomed.

like image 629
user2465039 Avatar asked Dec 28 '15 18:12

user2465039


People also ask

How is entity defined in DDD?

A domain entity in DDD must implement the domain logic or behavior related to the entity data (the object accessed in memory). For example, as part of an order entity class you must have business logic and operations implemented as methods for tasks such as adding an order item, data validation, and total calculation.

What is entity domain model?

Entities are Domain concepts that have a unique identity in the problem domain. Entities represent domain objects and are primarily defined by their identity, continuity, and persistence over time, and not only by the attributes that comprise them.

What is invariants in DDD?

In DDD, validation rules can be thought as invariants. The main responsibility of an aggregate is to enforce invariants across state changes for all the entities within that aggregate. Domain entities should always be valid entities. There are a certain number of invariants for an object that should always be true.

What is the difference between entity and value object?

The main difference between entities and value objects lies in the way we compare their instances to each other. The concept of identifier equality refers to entities, whereas the concept of structural equality - to value objects. In other words, entities possess inherent identity while value objects don't.


1 Answers

Domain

You say you need to be able to see past status changes, so the status history becomes a domain concept. A simple solution would then be the following:

  • Define a StatusHistory within the Document entity.
  • The StatusHistory is a list of StatusUpdate value objects.
  • The first element in the StatusHistory always reflects the current state - make sure you add the initial state as StatusUpdate value object when creating Document entities.

Depending on how much additional logic you need for the status history, consider creating a dedicated value object (or even entity) for the history itself.

Persistence

You don't really say how your persistence layer looks like, but I think creating queries against the first element of the StatusHistory list should be possible with every persistence mechanism. With a map-reduce data store, for example, create a view that is indexed by Document.StatusHistory[0] and use that view to realize the queries you need.

like image 65
theDmi Avatar answered Nov 11 '22 03:11

theDmi