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.
Related
I was trying to understand DDD value objects and entities, and have a minor doubt in that. I've read in a lot of articles that value objects does not have identity. I wanted clarity on whether that the identity referred here is a single attribute or a any composite attributes.
Lets say I have an inventory management service which has a business transaction called "Inventory Adjustment", what it does is simply adjusts the quantity of items at your warehouse. You can create an adjustment with multiple line items, each line item will have an ItemID and Quantity fields.
Note: Lets assume that an item can occur only once in an adjustment, meaning an adjustment cannot have multiple line items with same Item ID.
The user can edit an adjustment line item, delete line items and add new line items as well.
In this context, is adjustmentLineItem a value object OR an entity inside adjustment root aggregate?
The confusion I have is when we say VOs should not have an identity, does that mean it should not have an ID field or a composite identity as well. Because in my case, I would not need an ID field for the line item object, the AdjustmentID + ItemID serves as an identifier for me.
Also, is it fine to have the parent entity identifier inside a VO (like adjustmentID)?
Not related to this context, in general what is the reason why VOs should not have identities?
NOTE: I am relatively new to DDD and my understandings might be wrong.
There's a difference between identifier and identity.
An identifier is a value that identify something, is what an entity use to track its identity.
The identity instead is what tells you that an entity is different from another one, you can use a number to do it (like in case of sql db sequences) or some UUID, or basically use a value that acts as an identifier
Difference between value objects and entities reside in the identity of the latter.
If we have an entity, let's say a Person, and we do a change (mutate) to it (eg. change name), it still remain the same entity (a person changing name still remain the same person). That is not true for value objects, if we have an Address and we change its street it is a different Address.
When we reify this abstraction into code, we need something to track the identity of an entity, to be able to check and confront it with another one. In these cases we add a value in the entity that acts as an identifier, something that we know will stay the same for the entire lifecycle of the entity.
So the identifier can be seen as a value and it can be treat as such.
Then going back to the questions:
It seems to me that in your case the InventoryAdjustment is the entity (it has its own identity), and it contains the list of AdjustmentLineItem that could be seen as a value, containing the ItemId that is also a value.
AdjustmentLineItem is a VO itself
Code to work with things not having an identity is simpler as they can easily be immutable, avoiding a lot of issues (you can look for the immutability topic to understand them, or there's this famous talk about Values)
A final note about this rule:
Lets assume that an item can occur only once in an adjustment
This enforce the fact that the InventoryAdjustment is an entity, and this rule is one of its invariants.
The InventoryAdjustment has a value in it being a List<AdjustmentLineItem>, and could check the rule when someone try to mutate it. When doing domain models, the access for editing purposes to the state of the entity should be disallowed, no setter methods and make impossible for external code of the InventoryAdjustment to do things like:
inventoryAdjustment.getAdjustmentLineItemList().add(anAdjustmentLineItem)
but rather expose methods to do mutation, and internally check invariants:
inventoryAdjustment.addAdjustmentLineItem(anAdjustmentLineItem)
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.
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.
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.
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.