DDD: Can an entity have attributes of primitive data types? - object

The domain driven design differentiates two model types: entities and value objects. In the most examples the attributes of an entity are value objects or other entities, while the attributes of a value object are mostly simple strings, integers etc. (i. e. primitive data types).
That leads me to the question: Can an entity also have attributes of primitive data types? Or do you normally model each attribute of an entity as a value object or another entity?
The following might be an example to answer this question: We have an entity Comment with an attribute text. Is text simply a string variable or a value object?

While it is common attitude to compose an entity of another entities or value objects, it is not necessary. Please remember that you should think about an abstraction. Primitive types are ok when there is no business logic involved in using them. For example:
public class User {
private UserId id;
private String nickname;
private Date joinDate;
}
As you can see, nickname is an primitive type, because we can't do anything special with nickname. On the other hand joinDate should be Value Object, because dates has some logic (as comparing dates, adding, subtracting etc.)
Even in "Implemeting Domain-Driven Design" by Vaughn Vernon are examples of entities composed of primitive types.

Related

Uml class diagram alternative of map attribute

Through searching I found that in UML, aggregation(assuming that it's used properly) can be used to represent attributes in a class.
For example,
(Assume column can stand alone)
Then, using such example, if I want to replace the attribute: Column[] with map to represent the column's name, would it be correct to use an association class just like below? (In case, I'm not willing to put the column name in Column class as an attribute)
Association classes are used with simple associations. They have m-1-1-n multiplicity. The shared aggregation (as you used) has no defined semantics (and I recommend to simply not use it unless you have a domain specific and documented use for it). It's simply better to put the intended multiplicity on either side of an association.
An association class connects two classes, adding attributes and/or operations. Your example is "unconventional" since Table/Column have a simple relation which would not need an association class. A general example is the Student/Lecture relation where you can put an association class in between to record exam results, times etc.
Yes, I think that is a valid way of modelling the fact that you have some sort of key string that can be used to identify a Column of this Table.
Using a Map is one if the many possible implementations, so it's not a real equal to.
The advantage of modelling using the Association Class is that your model remains at the more abstract functional level and leaves out implementation details.
BTW. I would use a composition instead of an aggregation for the association between Table and Column, as there is an obvious strong ownership relation and life-cycle dependency between the two.
If you want to replace the attribute Column[] with map to represent the column's name and you are not willing to put the column name in Column class as an attribute and assuming that you want to follow UML specification precisely then you'll produce the model shown below:
Map<Key, Value> is usually understood as an associative container that contains key-value pairs Map.Entry<Key, Value> with unique keys. The container is modeled by the directional aggregation from Map<Key, Value> to Map.Entry<Key, Value>.
Map<Key, Value> and Map.Entry<Key, Value> are templates. Clause 7.3.3.1 of UML specification says that:
A template cannot be used in the same manner as a non-template Element of the same kind. The template Element can only be used to generate bound Elements or as part of the specification of another template.
According to clause 7.3.3.3:
A TemplateBinding is a relationship between a TemplateableElement and a template that specifies the substitutions of actual ParameterableElements for the formal TemplateParameters of the template.
Thus we have two bound elements that have TemplateBinding (marked by <> keyword) relationships with their templates:
ColumnNames which essentially is the name for Map<String, Column>
ColumnName which essentially is the name for Map.Entry<String, Column
According to clause 11.5.1 of the UML specification:
An Association classifies a set of tuples representing links between typed instances. An AssociationClass is both an Association and a Class.
ColumnName is AssociationClass representing the link between instances of String and Column classes. We use notation from clause 11.5.5, figure 11.35 to express that.
Finally, the directional composition association between Table and ColumnNames classes tells us that each instance of Table owns an instance of ColumnNames, i.e. set of column names.
Note that while ColumnNames and ColumName classes are usually hidden from the end-user by an implementation, they nevertheless exist.
I used BoUML to draw the diagram.

How to properly implement equality of entities and value objects in DDD?

Entities should not have equality comparison (https://www.youtube.com/watch?v=xRCOKKUSp9s).
Value objects should have equality comparison (https://www.youtube.com/watch?v=xRCOKKUSp9s)
Value objects can reference entities (Domain-Driven Design book)
Value objects are equal if all (or some?) of their attributes are equal (this one is not so explicitly stated, but it seems natural, https://martinfowler.com/bliki/ValueObject.html,http://enterprisecraftsmanship.com/2016/01/11/entity-vs-value-object-the-ultimate-list-of-differences/, https://projectlombok.org/features/Value). There might be rare exceptions (for example, (1, min) == (60, seconds)).
So if a value object has a reference to an entity, how should we include entity in that equals() comparison if we cannot call equals() on entity? Where is the flaw?
For me it is natural to implement Entity.equals() (usually based on type and ID). It is strange that I encountered that video (1).
Value objects are equal if all of their attributes are equal. Now let's see how is it for value objects that refer to entities. Entities needs to have a unique identifier (id) and that id is allowing the value object to refer to the entity. In other words the value object will have an attribute which have the entity id (userID for example) and in the vo.equal() you just include that attribute.
I don't think there is any need to implement Entity.equals(). Entities are designed to be unique even if they have all the same attributes and that's why we use ID to differentiate them. There might be the need to ask "is these two VOs referring to the same entity?" (same example in first video second 0:33) but other than that I don't see any need to compare Entities.

DDD entity constructor parameters

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.

Is every property of an Entity in domain driven design a value object?

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.

Value vs Entity objects (Domain Driven Design)

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.

Resources