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.
Related
I've found this great article where in the section on aggregates' structure, I can see a distinction being made between child entity (here: order item) and value object (here: address).
I'm not entirely sure how they differ on an architectural level. I'd like to say that both of them are value objects (aggregated within the root Order).
What am I missing in the picture?
Value Objects are much "values with methods" than they are "objects".
"Address" as a value, isn't fundamentally different from a primitive like integer. The significant difference between the two is that most generic programming languages don't come with a built in address type. So we have to roll our own -- or re-use one from a library.
In many modern languages, you can only roll your own by using the "object" idioms to create your customized data structure and the query semantics that you want.
Value objects are data with query semantics attached.
Entities, on the other hand, change over time. A way of thinking of an entity's implementation is that, under the covers, the entity is a mutable reference to a value.
void Entity::onChange(data) {
// dereference to get the current state value
val oldState = this.state;
// use a pure function to compute a new state value
val newState = stateChange(oldState, data);
// update the reference
this.state = newState;
}
The specific data structure being used to hold the state is an implementation detail of the entity of no interest to other elements in the solution.
A child entity is an entity, which is to say that it is an object with the responsibility for managing some implicit data structure. It is designed for change.
It's "just like the root", but on a smaller scale -- the root has a more complete sense of the entire context.
See also
Classes vs Data Structures -- Robert Martin
Perception and Action -- Stuart Halloway
I'm reading "Patterns, Principles, and Practices of Domain-Driven Design". The book suggests that properties of an Entity should be value objects in order to model domain's ubiquities language. I've seen many examples like EmailAddress or Age with only one field to model domain concepts. I'm confused about it. Is every property of an Entity a value object? Can you provide examples when we can use normal languages provided data types for properties?
No, not every property of an entity is a value object.
Properties of entities are one of the following:
As you already know, value objects. Value objects represent simple values without identity.
Primitives. These are just value objects from a DDD perspective, really. Primitives are ok to use in DDD, but take care not to become a victim of Primitive Obsession.
Entities. An entity can contain other entities. All entities that have direct (navigable) references between them are part of the same Aggregate. The "top-most" entity within an aggregate is called the Aggregate Root. Only the root has a global identity, inner entities have only local identity.
References to entities of other aggregates. Never reference these directly, use an ID. IDs themselves can in turn be modeled as value objects.
I think that your real question is: Is every value object a Class?
Because you can think that for the Age a Java Integer can be enough and this is true. So you have in your entity Person a value object Age of type Integer, there is no need of an age type.
OOP also says that an object is state + behaviour. In your Age case, I assume that it has no behavior so a simple primitive or wrapper class will do the trick, in fact I would go with option this because is simpler.
My advise is, go with a primitive/wrapper class and if you advert that some behavior is needed in that value object, make a class/type.
I'm starting to play with Domain Driven Design and have a question about ValueObjects :
Can they contains invariants or other specifications ?
Consider an immutable ValueObject :
ValueObject (
prop integer: Int
prop string: String
// Value and copy constructor
// Observers for integer and string
// Equality methods on integer and string value
)
Can I add some invariants such that integer > 0 & < 42. Or do they have to be simple transfer without any logic ?
I hope they can but need a confirmation.
A value object (VO) encapsulates a value and its business requirements . This is its purpose: to model a business concept (with its constraints) which happens to be a simple (not always single) value.
A VO is not a Data transfer object (DTO) precisely because it defines a business concept that is valid only in the containing bounded context, while a DTO is meant to cross boundaries.
Value objects should handle the invariants for the data that they encapsulate, or at least as much of it as they can. I tend to do the following, which is actually similar to entities except for the immutable bit:
Constructors should make sure it is created in a valid state
The VO's state is encapsulated, and all changes to it are done through controlled methods/etc
Because value objects are immutable, method changes return a new value object rather than updating the existing state
Having the value objects own their own business logic really helps clean up the code in the entities that use these value objects. This can become a problem with big aggregates\entities, so look for opportunities to pull this behavior out into value objects.
It also makes unit testing lots of edge cases MUCH easier, as you are testing the value object on its own.
Your entity may need to do validation across multiple value objects before decides a change CAN happen, but then the value object is responsible for the change itself.
Given tha nature of ValueObjects in DDD,it can be considered a collection of them as a container that contains the result set of a database query?
for example,this pseudocode could be a reasonable usage of ValueObject concept?:
List<ValueObject> resultSet = GetValueObjectsFromDB();
List<ValueObject> GetValueObjectsFromDB()
{
return ExecuteCommand("SELECT * FROM dbo.AnEntity");
}
I think you confuse Value Object which is one of the building blocks of Domain Driven Design and DTO (Data Transfert Object) which is a dumb data container.
Value Object : An object has no conceptual identity. They should be treated as immutable. Value Object plays his role in a domain model and very often have a behaviour associated with it.
DTO : It's just a dumb data container that can be used for transfering data on the wire or between architectural layers.
What you would use on the 'query' side is a DTOs tailored to your specific needs. If you want to display it on the screen or transfert this data to another system the DTOs is the way to do it.
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.