All material on DDD specify this as a strict no no, but i recently came across a scenario that makes a compelling case for thinking otherwise. Imagine 2 aggregate roots Template and Document where Template --> (1:n) TemplateParam, Document --> (1:n) ParamValue and finally the 2 roots have a reference Document --> (n:1) Template.
Given aggregate root constraint ParamValue should not persist a reference to TemplateParam, only it can refer it through a transient reference obtained through Template aggregate root. Now if i want to have a rule enforce like "each ParamValue of document should refer to a valid TemplateParam belonging to the Template referred to by its owning document". Ideally at db level i would let ParamValue have FK to the TemplateValue, how to do it in DDD paradigm ??
Aggregate Roots are there for a reason. They act as a single entry point to a group of related entities in order to enforce their invariants. They make sure that no external object can mess up with these entities and potentially violate their invariants.
However, in your particular scenario, even if ParamValue holds a direct reference to TemplateParam, TemplateParam is not at risk of being modified by an entity in the Document aggregate. The value associated to a parameter for a given document will be modified, but not the parameter per say.
To make sure this is the case, you can make TemplateParam an immutable value object :
(in C#)
public class TemplateParam
{
private readonly string name;
public TemplateParam(string name)
{
this.name = name;
}
public string Name
{
get { return name; }
}
}
Thus you can encapsulate TemplateParam in ParamValue with no risk that one of the Template aggregate's invariants will be broken due to the "externalization" of TemplateParam.
Technically speaking that may be a violation of DDD's aggregate root constraint, but I don't believe it is one in spirit as long as you keep the "externalized" entity immutable and don't modify the object graph it originally belongs to.
One way you could go about this is to have the Template entity have a factory method for creating Document instances, which can enforce the constraint that all ParamValue instances are associated with appropriate TemplateParam. If the document is immutable then you're done. Otherwise, you can apply updates to the document through its associated template. This template can be referenced directly from the document or with an ID in which case the encapsulating application service would retrieve it when required for an operation. Direct references between ARs are not a strict violation of DDD, in fact the blue book specifies that are the only things that can be referenced by external ARs. It has become a constraint as of late because of other considerations such as consistency, performance, ORM mapping, etc. Take a look at this series of articles on effective aggregate design for some inspiration.
Related
In the book, Eric Evans shows an example where an VALUE OBJECT holds ENTITIES. VALUE OBJECTS are immutable, ENTITIES not.
The question is: If an ENTITY that
is referenced from an VALUE OBJECT change its state, was the immutability been broken?
In my opinion it doesn't break the immutability, because the "value" of the
object lies on the ENTITIES array, not on their states.
What do you guys think?
It depends if you can mutate the entities directly through the VO or not.
Imagine a VO instance that can be shared between multiple objects. If the VO contains a mutable entity and exposes it as a public member, multiple clients may update the entity concurrently. This leads to problems you would expect not to happen with actual immutability.
If the VO only holds the ID of the referenced entity on the other hand, you would have to fetch a brand new instance from a Repository before changing it, avoiding the shared mutable state issue.
If you have an entity with a value object as an attribute.
Which would be the parameters of the entity constructor, the value object? Or the primitive types of the value object?
First I did it building the value object outside the entity and I passed the value object to the entity constructor... but then I realized that maybe it would be the entity itself that has to build the value object.
I thought this because the entity and the value object are in fact an aggregate, and it is supposed that you have to access the inside of an aggregate through the aggregate root, i.e., through the entity.
So which is the right way? Is it allowed to deal with the value object outside the entity? Or the value object just can be used by the entity?
Thank you.
EDIT:
For example, I have an entity "Task" that is the aggregate root. This entity has a value object "DeliveryDate" (in format "dd/mm/yyyy hh:mm"). The entity has more value objects too.
class DeliveryDate extends ValueObject {
private String formattedDeliveryDate;
private DeliveryDate() {
super();
}
DeliveryDate ( String formattedDeliveryDate ) {
this();
this.setFormattedDeliveryDate ( formattedDeliveryDate );
}
private void setFormattedDeliveryDate ( String formattedDeliveryDate ) {
<< check that the string parameter "formattedDeliveryDate" is a valid date in format "dd/mm/yyyy hh:mm" >>
this.formattedDeliveryDate = formattedDeliveryDate;
}
........
The entity constructor:
Task ( TaskId taskId, Title title, Delivery deliveryDate, EmployeesList employeesList ) {
this();
this.setTaskId(taskId);
this.setTitle(title);
this.setDeliveryDate(deliveryDate);
this.setEmployeesList(employeesList);
}
My doubt is: Is this ok? (passing to the constructor the DeliveryDate object)
Or should I pass the string? (and the constructor creates the DeliveryDate object)
I think it's more a question of "should the outside of the aggregate know about the DeliveryDate concept?"
In general my doubt is about any value object of any entity, not just Task and DeliveryDate (this is just an example).
I have asked the question about the constructor, but it's valid for factories too (if the process of creating an instance is complicated)... should the aggregate factory parameter be the value object? or the primitives to create the value object?
In your case it might seem that the two solutions are similar. It doesn't really matter if you create the value object outside or inside of the entity. But think about when your entity will have more than one value object, the entity constructor will contain too much logic in order to make sure it creates the VOs correctly and at the same time enforce the entity's invariants.
One solution to avoid this unnecessary complexity is to use factories. The factory will abstract the creation process and this will keep you entity code simple.
In DDD, factories are very useful for creating aggregates. In the blue book there is a whole chapter about factories and here is good article about the use of factories in DDD http://culttt.com/2014/12/24/factories-domain-driven-design/
Edit
My doubt is: Is this ok? (passing to the constructor the DeliveryDate object) Or should I pass the string? (and the constructor creates the DeliveryDate object)
Yes, it is ok. Task should not know about how to create the value objects. You should not pass the strings cause that will add more complexity and responsibilities to the Task constructor.
I think it's more a question of "should the outside of the aggregate know about the DeliveryDate concept?"
Yes, it is not problems that the outside of the aggregate knows about the DeliveryDate. It is the same as knowing about strings and integer. Value objects are simple to deal with and reason about and they are part of the domain so I think there is no problems in dealing with them outside of the aggregate.
should the aggregate factory parameter be the value object? or the primitives to create the value object?
Here I would say the Factory should receive the primitive types and encapsulate the objects creation. cause if you pass the values objects to the factory it will just pass the same parameters to the Entity constructor and that is a middleman code smell.
Domain Driven Design doesn't offer any specific guidance here.
A common case might look something like this: we've retrieved a DTO from the database, and now want to create a Entity from it....
class Entity {
private Value v;
Entity (Value v) {
if (null == v) throw new IllegalArgumentException();
this.v = f;
}
Entity (DTO dto) {
this(new Value(dto));
}
// ...
}
Does it really matter if you invoke the second constructor rather than the first? Not much.
A language check:
DTOs are not retrieved from database. What you retreive from a database is an aggregate, not a DTO
I had to abandon that idea - that definition leads to too many problems.
For example, in event sourced designs, the database typically stores representations of events, not aggregates.
Even in traditional designs, it doesn't hold up -- the boundaries of your aggregates are defined by the constraints enforced by the domain model. Once you take the data out of the domain model, what you have left is just representations of state. Expressed another way, we save state in the database, but not behaviors, and not constraints -- you can't derive the constraints from the saved data, because you can't see the boundaries.
It's the model, not the database, that decides which data needs to be kept internally consistent.
I tend to use the term DTO because that's its role: to carry data between processes -- in this particular instance, between the data base and the domain model. If you wanted to use message or document instead, I wouldn't quibble.
I'm reading a book by Eric Evans DDD.
And I found a contradiction.
Chapter books about aggregates:
Choose one ENTITY to be the root of each AGGREGATE, and control all
access to the objects inside the boundary through the root.
Chapter books about repositories:
A subset of persistent objects must be globally accessible through a
search based on object attributes. Such access is needed for the roots
of AGGREGATES that are not convenient to reach by traversal. They are
usually ENTITIES, sometimes VALUE OBJECTS with complex internal
structure, and sometimes enumerated VALUES. Providing access to other
objects muddies important distinctions.
Provide REPOSITORIES only for AGGREGATE roots that actually need
direct access.
It can be concluded that the root of the aggregate can be:
entity
value object
enumerated values
Correctly I understood everything?
Or may be right:
Provide REPOSITORIES only for
aggregate roots
value objects
enumerated values
?
And what is enumerated values(which needs its own repository!)?
Per #Marco's comment above, the root of an aggregate can only be an entity (i.e. something with an ID property). An example of this would be an Order object. No matter how many attributes you change on an Order its quality is determined by its Id property and nothing else.
A value object (often implemented as a struct in many languages) does not have an ID. A common example of this would be a Money value object with a Dollars property and Cents property. Because it has no ID, the concept of querying it by ID does not apply, and thus the concept of a repository does not apply. An aggregate could have a value object as a property, though (e.g. the Total property on an Order aggregate).
An enumerated type is just a list of name/value pairs. It uses the enum keyword in several languages. Again, there's no ID for the enum nor any of its members, so the concept of a repository does not apply. The concept of an enum is useful in DDD because it helps express the domain model better than, say, magic numbers e.g. order.Status = OrderStatus.Submitted vs order.Status = 1.
a) I'm a bit puzzled whether in most cases we should only have a factory that produces the entire Aggregate or should we also have a factory that creates only the Aggregate root?
b) Should a factory that builds the entire Aggregate build both root and non-root objects by itself or should it delegate the building of non-root entities/VOs to other factories?
Thus, if Aggregate contains 5 different types of non-root entities, should Aggregate factory create these non-root entities by itself or should we have additional five factories ( one factory for each non-root entity ), to which Aggregate factory would delegate the creation of particular type of non-root entity?
Thank you
In Eric Evans' DDD book, page 138, it's written in bold:
Create entire aggregates as a piece, enforcing their invariants.
Then in the next page:
A FACTORY should only be able to produce an object in a consistent
state. For an ENTITY, this means the creation of the entire AGGREGATE
[...]
Concretely, this means that you would only have one factory to create the entire aggregate. There may be other classes (factories) involved in building your non-root entities or value objects, but there is only one factory responsible for creating an aggregate. This factory creates a full aggregate, not just a root object.
The creation of sub-root objects (for example, an OrderItem for an Order) is handled by the root entity itself, so it can enforce variants in a manner invisible to the outside world.
So a typical flow could be:
var newOrder = orderFactory.CreateOrder(customer);
newOrder.AddOrderItem(product, quantity);
A factory might be used within the entity, but it shouldn't be accessed by the outside world.
public class Order
{
private OrderItemFactory _orderItemFactory;
public AddOrderItem(Product product, int Quantity)
{
var newOrderItem = _orderItemFactory.CreateOrderItem(product, quantity);
}
}`
I have just started reading DDD. I am unable to completely grasp the concept of Entity vs Value objects.. Can someone please explain the problems (maintainability, performance.. etc) a system could face when a Value object is designed as a Entity object? Example would be great...
Reduced to the essential distinction, identity matters for entities, but does not matter for value objects. For example, someone's Name is a value object. A Customer entity might be composed of a customer Name (value object), List<Order> OrderHistory (List of entities), and perhaps a default Address (typically a value object). The Customer Entity would have an ID, and each order would have an ID, but a Name should not; generally, within the object model anyway, the identity of an Address probably does not matter.
Value objects can typically be represented as immutable objects; changing one property of a value object essentially destroys the old object and creates a new one, because you're not as concerned with identity as with content. Properly, the Equals instance method on Name would return "true" as long as the object's properties are identical to the properties of another instance.
However, changing some attribute of an entity like Customer doesn't destroy the customer; a Customer entity is typically mutable. The identity remains the same (at least once the object has been persisted).
You probably create value objects without realizing it; anytime you are representing some aspect of an Entity by creating a fine-grained class, you've got a value object. For example, a class IPAddress, which has some constraints on valid values but is composed of simpler datatypes, would be a value object. An EmailAddress could be a string, or it could be a value object with its own set of behaviors.
It's quite possible that even items that have an identity in your database don't have an identity in your object model. But the simplest case is a composite of some attributes that make sense together. You probably don't want to have Customer.FirstName, Customer.LastName, Customer.MiddleInitial and Customer.Title when you can compose those together as Customer.Name; they'll probably be multiple fields in your database by the time you think about persistence, but your object model doesn't care.
Any object that is collectively defined by all of it attributes is a value object. If any of the attributes change you have a new instance of a value object. This is why value objects are defined as immutable.
If the object is not fully defined by all of its attributes then there are a subset of attributes that make up the identity of the object. The remaining attributes can change without redefining the object. This kind of object cannot be defined at immutable.
A simpler way of making the distinction is to think of value objects as static data that will never change and entities as data that evolves in your application.
Value Types :
Value types do not exist on his own, depends on Entity types.
Value Type object belongs to an Entity Type Object.
The lifespan of a value type instance is bounded by the lifespan of the owning entity instance.
Three Value types: Basic(primitive datatypes), Composite(Address) and Collection(Map, List, Arrays)
Entities:
Entity types can exist on his own (Identity)
An entity has its own life-cycle. It may exist independently of any other entity.
For example: Person, Organisation, College, Mobile, Home etc.. every object has its own identity
I don't know if the following is correct, but I would say that in the case of an Address object, we want to use it as a Value Object instead of an Entity because changes to the entity would be reflected on all linked objects (a Person for instance).
Take this case: You are living in your house with some other people. If we would use Entity for Address, I would argue that there would be one unique Address that all Person objects link to. If one person moves out, you want to update his address. If you would update the properties of the Address Entity, all people would have a different address. In the case of a Value Object, we would not be able to edit the Address (since it is immutable) and we would be forced to provide a new Address for that Person.
Does this sound right? I must say that I was/am also still confused about this difference, after reading the DDD book.
Going one step further, how would this be modelled in the database? Would you have all properties of the Address object as columns in the Person table or would you create a separate Address table that would also have a unique identifier? In the latter case, the people living in the same house would each have a different instance of an Address object, but those objects would be the same except for their ID property.
address can be entity or value object that depends on the busiess process. address object can be entity in courier service application but address can be value object in some other application. in courier application identity matters for address object
3 distinction between Entities and Value Objects
Identifier vs structural equality:
Entities have identifier,entities are the same if they have the same
identifier.
Value Objects on beyond the hand have structural equality, we consider two
value objects equal when all the fields are the same. Value objects cannot
have identifier.
Mutability vs immutability:
Value Objects are immutable data structures whereas entities change during
their life time.
Lifespan: Value Objects Should belong to Entities
In a very simple sentence I can say, we have three types of equality:
Identifier equality: a class has id filed and two objects are compared with their id field value.
Reference equality: if a reference to two objects has a same address in memory.
Structural equality: two objects are equal if all members of them are matched.
Identifier equality refers only to Entity and structural equality refers to Value Object only. In fact Value Objects do not have id and we can use them interchangeably. also value objects must be immutable and entities can be mutable and value objects will not have nay table in database.
I asked about this in another thread and I think I'm still confused. I may be confusing performance considerations with data modelling. In our Cataloging application, a Customer doesn't change until it needs to. That sounds dumb - but the 'reads' of customer data far outnumber the 'writes' and since many many web requests are all hitting on the 'active set' of objects, I don't want to keep loading Customers time and again. So I was headed down an immutable road for the Customer object - load it, cache it, and serve up the same one to the 99% of (multi-threaded) requests that want to see the Customer. Then, when a customer changes something, get an 'editor' to make a new Customer and invalidate the old one.
My concern is if many threads see the same customer object and it is mutable, then when one thread starts to change it mayhem ensues in the others.
My problems now are, 1) is this reasonable, and 2) how best to do this without duplicating a lot of code about the properties.
Consider the following examples from Wikipedia, in order to better understand the difference between Value Objects and Entities:
Value Object: When people exchange dollar bills, they generally do not
distinguish between each unique bill; they only are concerned about the face
value of the dollar bill. In this context, dollar bills are Value Objects. However,
the Federal Reserve may be concerned about each unique bill; in this context each
bill would be an entity.
Entity: Most airlines distinguish each seat uniquely on every flight. Each seat is
an entity in this context. However, Southwest Airlines, EasyJet and Ryanair do
not distinguish between every seat; all seats are the same. In this context, a seat is
actually a Value Object.