Should uniqueness be ignored when deciding if something is an Entity or Value Object? - entity

Is uniqueness considered a persistence concern in DDD?
The reason I ask is because I have a Customer object in an order quoting context. e.g. an order is for a customer and the customer must pay a certain rate.
Technically, I won't allow a customer to have the same code or name as another. Which means if I have two Customer objects with the same code and name, they'll always be treated the same like a value object.
But instinctively, a Customer feels like an entity. Is the unique constraint throwing me off, or am I right to think it's a value object?
The order quoting context will also allow customers to be added/edited/removed from an admin page. Could the confusion be caused by this? Should admin pages be part of another context where Customer is an entity, and the order quoting context will use Customer as a value object?

This is an excellent question, and you partially answered it already, your Customer is an Entity in your bounded context of administration.
A good rule of thumb to decide whether or not an object is an entity is to think with the concept of identity. If your object require an identity which will stay the same as the time flies, even if the person's name or contact details can change then its likely an Entity.
However, with that concept defined, you can have a CustomerId, which is composed of the invariant from a business point of view, in your case the code and name.
This CustomerId is not a technical ID, its a business ID, and your entity's identity will be this ID. In the Order quoting bounded context, you can then reference your Customer using this same object (probably defined somewhere in a shared context, or by duplicating the code: its ok in DDD to duplicate some code to promote loose coupling).

Related

Class Diagram: In A Composition Relationship Should a Child Class Always Have An ID Field?

I'm having a hard time converting my database tables and foreign keys to a class diagram with classes and associations.
My question is:
"In in a composition relationship, should a child class always should have an ID field?".
In my CD, there are 2 compositor classes: PurchaseItem and PurchaseFinisher, which composite Purchase class. PurchaseItem already comes with an ID field from its table but, PurchaseFinisher doesn't because it is filtered by the id_purchase and id_payment_method foreign keys.
thanks in advance.
This is my DB diagram:
I can't see redundancy in between Purchase or Product, as you said. Could you, please, show me that based on my DB diagram? My tables are well modeled (hope so). My fault is in the classes definition.
In a class diagram, no class requires an id property: each class instance (aka object) has its own identity with or without explicit id property.
In a database, you need of course an explicit id property to uniquely identify the object among others in the database and find it back. By the way, you may annotate such properties with a trailing {id} . UML does not define any semantic for it, but it is in general sufficiently expressive to help database designers.
In the case of composition, the main question is whether a composed object can easily be identified by alternate means. There are several related ORM database techniques, for example:
you can use the owning object’s id together with another property if this is sufficient to identify the element. The two together would make a composite primary key in database.
you can use a unique id to identify the object (surrogate primary key) and use the id of the owning object as foreign key.
For PurchaseItem you have everything that is needed, although the diagram does not tell which of the two approaches you’ll use (e.g is the id unique globally, or unique within the purchase?).
But for PurchaseFinisher it is unclear if you could uniquely identify an occurence. If a payment method can only be used once per purchase, it’s fine as it may be used to identify the object.
If it would be allowed to pay two times the same amount (half of the overall price) in the same currency with the same payment methods, you’d have undistinguishable duplicates. So, some kind of identifier will be needed from the database point of view.

DDD Aggregates: Entity holding identifier to Non-Root Entity in another Aggregate

I'm trying to understand Best Practise for relationships between entities and aggregates.
Imagine a design where you have a Product Aggregate, made up of of two entities:
Aggregate Root: Product
Child Entity: Sku
Where a product can have many Skus. The part numbers and names of the Skus and Product are invariant, in that changing the name of one must transactionally ensure the other is updated. Likewise, the product aggregate needs to ensure there are never duplicate Skus.
We have another Aggregate: StorageLocation. where 1 or more Skus are stored. However it's important that the StorageLocation know the specific Sku it's storing. ie. A StorageLocation in Canada should store the Sku local to that country, and not a Sku intended for the US market.
This implies to me that the StorageLocation needs to keep a reference to the Sku (as a reference to the Product Aggregate Root by itself does not provide enough information to determine the Sku being Stored).
From my readings this seems to break the principle that another Aggregate should not hold a reference to a non-root entity in another Aggregate. So question:
Is holding just an identifier to the Product and Sku in the StorageLocation aggregate acceptable?
I'm aware that a transient reference is deemed allowable, but in this instance (at least as far as I can tell) this information needs to be stored. As mentioned, storing a reference to the Product (or ProductId) is not enough.
Product and Skus have natural identifiers (Part Number, Sku Number). Does this provide greater flexibility for storing these values in the StorageLocation aggregate as they have meaning beyond technical implications.
Am I approaching this the wrong way and need to look at things differently. I often find it difficult to break out of a PK / FK mindset.
Thanks
The guidance to not store a reference to a child entity is founded on good principals but I believe often causes confusion. The goal is actually that the child entity does not necessarily have a 'globally unique' identifier, and that no repositories give direct access to the child entity using such a globally unique identifier.
However, if your StorageLocation holds the globally unique identifier for the Product, as well as a possibly locally unique identifier for the SKU, then there is nothing wrong with patterns such as:
var storageLocation = _storageLocationRepository.Get(id);
var product = _productRepository.Get(storageLocation.ProductId);
product.DoSomethingToSku(storageLocation.SkuId);
The key is that by ensuring that you always obtain the product from a repository, and then interact with the child entity via the product, you are ensuring the product has the opportunity to protect it's own invariants.
So to summarise:
Feel free store an identifier to a child entity as long as you also store the global identifier for its aggregate root.
In this case, the child entity id may be locally unique or globally unique - it doesn't matter as long as the access to the child entity is via the aggregate root.
Never load a child entity directly from the a repository and call methods on it - as then the aggregate root has no chance to protect its invariants.
In fact, you should never even have a repository for a child entity
Is holding just an identifier to the Product and Sku in the StorageLocation aggregate acceptable?
Yes, because identifiers are value objects in DDD, storing the identifier in the StorageLocation aggregate does not break the rule of holding a reference to another aggregate's child entity because the value object is just a value object and no longer has any direct association with the originating aggregate.
I'm aware that a transient reference is deemed allowable, but in this instance (at least as far as I can tell) this information needs to be stored. As mentioned, storing a reference to the Product (or ProductId) is not enough.
The dehydration of the StorageLocation aggregate root back to the db should include everything that needs to be persisted. The infrastructure layer determines how your domain objects are stored in the physical repository and could be a completely different model design than your domain model depending on the concerns with the persistence technology.
Product and Skus have natural identifiers (Part Number, Sku Number). Does this provide greater flexibility for storing these values in the StorageLocation aggregate as they have meaning beyond technical implications.
There is nothing to compare "greater flexibility" to because you would only use natural identifiers or transient references for referring to entities inside the Product aggregate from the StorageLocation aggregate.
Am I approaching this the wrong way and need to look at things differently. I often find it difficult to break out of a PK / FK mindset.
Keep in mind that the persistence layer concerns should not entangle with the domain model and that the intent is to make the domain model clear and synonymous with current business rules.

Value objects in DDD

I have Order and OrderType classes in my sale module, that OrderType class uses for some categorization goals and applying some business rules on Orders. each class has its own table.
I want to apply DDD techniques on my project.
So, I think that the Order is an Aggregation root, but what about OrderType?
Is it also contained in Order aggregation or is it a Value object?
I think it will be a value object.
Am I correct?
There is a common question "Entity vs Value Object".
what about OrderType? Is it also contained in Order aggregation or is
it a Value object? I think it will be a value object. Am I correct?
I would say that OrderType is an entity but it depends an your domain.
The difference between Value Object and Entity is simple:
Value objects are considered the same when all their properties are equal.
When you care only about the attributes and logic of an element of the
model, classify it as a value object. Make it express the meaning of
the attributes it conveys and give it related functionality. Treat the
value object as immutable.
Entities are considered the same when they have the same identity.
When an object is distinguished by its identity, rather than its
attributes, make this primary to its definition in the model. Keep the
class definition simple and focused on life cycle continuity and
identity.
There is a simple “litmus test” for Entities:
If two instances of the same object have different attribute values,
but same identity value, are they the same entity?
As always "it depends..."
From your description it seems that it should be a Value object or, as Eric Evans means, Readonly entity without identity.
Should OrderType be a separate entity (can be sent to another objects) or it is small part of Order object?
Should OrderType has identity and be unique object even with same fields (Code, Title)?
Yes -> Entity with ID; No -> Value object
It's possible you may not even need a class to model OrderType. An enum with an attribute may be sufficient if your programming language supports it, e.g.
public enum OrderType {
[Code("ABC123")]
OneTime = 0,
[Code("XYZ456")]
Repeating = 1
}

Separate table for Value Objects on NHibernate

I'm new to DDD and NHibernate.
In my current project, I have an entity Person, that contains a value object, let's say Address. Today, this is fine. But maybe one day I will have a requirement that my value object (in this case Address), will have to become an entity.
Before trying to model this on a DDD-way, in a more data-centric approach, I had a table Person, with an Id, and another table Address, whose PK was actually an FK, it was the Id of a Person (ie, a one-to-one relationship).
I've been reading that when I map a Value Object as a Component, its value will get mapped as columns on my Entity table (so, I would not have the one-to-one relationship).
My idea was that, when needed, I would simply add a surrogate key to my Address table, and then it becomes an Entity.
How should I design this using NHibernate? Should I already make my Address object an Entity?
Sorry, I don't even know if my questions are clear, I'm really lost here.
In the system we are building, we put Value-Objects in separate tables. As far as I know, NHibernate requires that an id must added to the object, but we ignore this and treat the object as a Value-Object in the system. As you probably know, a Value-Object is an object that you don't need to track, so we simply overlook the id in the object. This makes us freer to model the database the way we want and model the domain model the way we want.
You can Join and make it a Component allowing nHibernate to map it as a proper value object instead of an entity.
This way you won't need any virtual properties nor an empty protected ctor (it can be private).
Join("PROPOSAL_PRODUCT", product =>
{
product.Schema(IsaSchema.PROPOSALOWN);
product.KeyColumn("PROPOSAL_ID");
product.Component(Reveal.Member<Proposal, Product>("_product"), proposalProduct =>
{
proposalProduct.Map...
});
});

Should one include ID as a property on objects persisted to a database?

I am creating the model for a web application. The tables have ID fields as primary keys. My question is whether one should define ID as a property of the class?
I am divided on the issue because it is not clear to me whether I should treat the object as a representation of the table structure or whether I should regard the table as a means to persist the object.
If I take the former route then ID becomes a property because it is part of the structure of the database table, however if I take the latter approach then ID could be viewed as a peice of metadata belonging to the database which is not strictly a part of the objects model.
And then we arrive at the middle ground. While the ID is not really a part of the object I'm trying to model, I do realise that the the objects are retrieved from and persisted to the database, and that the ID of an object in the database is critical to many operations of the system so it might be advantageous to include it to ease interactions where an ID is used.
I'm a solo developer, so I'd really like some other, probably more experienced perspectives on the issue
Basically: yes.
All the persistence frameworks ive used (including Hibernate, Ibatis) do require the ID to be on the Object.
I understand your point about metadata, but an Object from a database should really derive its identity in the same way the database does - usually an int primary key. Then Object-level equality should be derived from that.
Sometimes you have primary keys that are composite, e.g first name and last name (don't ever do this!), in which cases the primary key doesn't become 'metadata' because it is part of the Object's identity.
I generally reserve the ID column of an object for the database. My opinion is that to use it for any 'customer-facing' purpose, (for example, use the primary key ID as a customer number) you will always shoot yourself in the foot later.
If you ever make changes to the existing data (instead of exclusively adding new data), you need the PK. Otherwise you don't know which record to change in the DB.
You should have the ID in the object. It is essential.
The easiest use case to give as an example is testing equality:
public bool Equals(Object a, Object b) { return {a.ID = b.ID}; }
Anything else is subject to errors, and you'll find that out when you start getting primary key violations or start overwriting existing data.
By counterargument:
Say you don't have the ID in the object. Once you change an object, and don't have it's ID from the database, how will you know which record to update?
At the same time, you should note that the operations I mention are really private to the object instance, so ID does not necessarily have to be a public property.
I include the ID as a property. Having a simple unique identifier for an object is often very handy regardless of whether the object is persisted in a database or not. It also makes your database queries much more simple.
I would say that the table is just a means to persist an object, but that doesn't mean the object can't have an ID.
I'm very much of the mindset that the table is a means to persist the object, but, even so, I always expose the IDs on my objects for two primary reasons:
The database ID is the most convenient way to uniquely identify an object, either within a class (if you're using a per-table serial/autonumber ID) or universally (if you're maintaining a separate "ID-to-class" mapping). In the context of web applications, it makes everything much simpler and more efficient if your forms are able to just specify <input type=hidden name=id value=12345> instead of having to provide multiple fields which collectively contain sufficient information to identify the target object (or, worse, use some scheme to concatenate enough identifying information into a single string, then break it back down when the form is submitted).
It needs to have an ID anyhow in order to maintain a sane database structure and there's no reason not to expose it.
Should the ID in the object read-only or not? In my mind it should be read-only as by definition the ID will never change (as it uniquely identifies a record in the database).
This creates a problem when you create a new object (ID not set yet), save it in the database through a stored procedure which returns the newly created ID then how do you store it back in the object if the ID property is read-only?
Example:
Employee employee = new Employee();
employee.FirstName="John";
employee.LastName="Smith";
EmployeeDAL.Save(employee);
How does the Save method (which actually connects to the database to save the new employee) update the EmployeeId property in the Employee object if this property is read-only (which should be as the EmployeeId will never ever change once it's created).