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.
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.
In my app Core Data model I have Sheet and Text entities. Sheet entity can have two Text's: privacyNotes and termsOfUse.
Both of Text type. So in XCode data modeler I create to-one relationships called "privacyNotes" and "termsOfUse" in Sheet with Text destination. Next goes to-one relationship "sheet" in Text. Then I select that Text.sheet relationship as inverse for Sheet.privacyNotes. So far so good. But when I set same Text.sheet relationship as inverse for Sheet.termOfUse XCode deletes this relationship as inverse Sheet.privacyNotes!
I understand that relationships in DB can be not so simple compared to Objective-C objects relationships, but I really don't get why SQLite or (CoreData) can't reuse one relationship as inverse for FEW other relationships?
A little peek under the abstraction hood might be enlightening*: a relation can only be the inverse for exactly one other relation because, in the backing store, they're represented by the same data. If a Text and a Sheet can have a certain relationship, Core Data does what a good human data modeler would do and stores that relationship as succinctly as possible. The relation properties of the entity objects are just ways of looking at that relationship.
To get the effect of what you're going for: go ahead and give Sheet properties for privacyNote and termsOfUse; but give Text properties like sheetIAmTermsFor and sheetIAmPrivacyNoteFor, and set them as inverses appropriately. Then in the Text class, add a synthetic property along these lines:
// in interface
#property (nonatomic, readonly) Sheet *sheet;
// in impl
-(Sheet *)sheet
{
if ([self sheetIAmTermsFor])
return [self sheetIAmTermsFor];
else
return [self sheetIAmPrivacyNoteFor];
}
If you want to write a setter too, you'll have to decide which role that setter should bestow on the Text (which Core Data can't figure out for you, another reason a property can't be the inverse of two different properties.)
If you need to enforce a constraint that a Text can only ever be a "privacyNote" or a "terms" but never both, override the setters for sheetIAmTermsFor and sheetIAmPrivacyNoteFor, following Apple's pattern in the docs, and have each null the other property when set.
(* Apple regards the SQLite databases Core Data generates as private to their implementation, but inspecting their schemas can be very educational. Just don't be tempted to write shipping code that goes behind CD's back to poke at the db directly.)
You are far better off having a one to many relationship between Sheet and Text with a validation limit of 2. Then you should have a type property in the text which declares it as either a privacyNotes or termsOfUse. From there you can add convenience methods to your Sheet subclass that allows you to retrieve either one.
Suppose I have the following data model:
Entity Person
Attribute name String
Attribute personType String
Attribute dailyRecords
Entity CarpenterDailyRecord
Attribute numberOfNailsHammered Int
Attribute picNameOfFinishedCabinet String
Entity WindowWasherDailyRecord
Attribute nameOfBuildingWashed String
Attribute numberOfWindowsWashed Int
I would like to establish a to-many relationship between the Person.dailyRecords and 1 of the daily record entities (which changes depending on the person type). Of course, i could create a CarpenterPerson and WindowWasher entity which each points to it's unique daily record structure, but i have to group people together in my app somehow.
so if i do a Group Entity:
Entity Group
Attribute people array
i'm still stuck. how do i point to multiple & different Person entities?
There must be an obvious answer, it's just i'm so new to all of this. thanks!
Create a parent (DailyRecord) entity that handles the relationship (Person <-->> DailyRecord). [CarpenterDailyRecord|WindowWasherDailyRecord] then inherits from DailyRecord.
The risk with this, however, is that all of the children (WindowWasherDailyRecord, CarpenterDailyRecord) will be in one table in the underlying sqlite structure and therefore can cause a performance impact. This is not a reason to avoid inheritance, just something to be aware of while designing your data model.
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.