Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have an entity and I've realised that there is a group of properties that work together. So, I moved them to a value object (together with their behavior) and now I have a reference from my entity to this value object.

I've read "Domain Driven Design Quickly" (PDF) and I came across the following statement when explaining Value objects:

If Customer is an entity object, then one instance of this object, representing a specific bank client, cannot be reused for account operations corresponding to other clients. The outcome is that such an instance has to be created for every client. This can result in system performance degradation when dealing with thousands of instances.

But I'm still not clear exactly what this means. Is my new object a value object or should it be an entity? I am having trouble reasoning whether it should in fact be an entity. In other words, what questions should I ask in my domain to assure me that it should be a value object?

share|improve this question
up vote 3 down vote accepted

To expand on the answer by ques, a value object does not have a surrogate identity such as a customer number, but the object itself is its own natural identity.

Take an address for example. All addresses are unique, and the various components of an address (number, street name etc) make up the addresses identity. When you move house, you don't pick up your address, change the number on the door and take it with you, you get a new address. As such value objects don't change - they are immutable. However you could have 2 or more customers living at the same address, in which case the address value is reusable - it is not tied to a single customer entity.

share|improve this answer
    
Thanks Matt for replying. I am starting to understand what a value object is but my question was more to do with the paragraph I read in the pdf mentioned above. The paragraph talks mentions "cannot be reused for account operations" and "performance degradation". This is what confused me as I don't know what it is referring to. Can you help clear it up? – JD01 Dec 19 '11 at 11:15
1  
The can not be reused part mens that you can not use one object for multiple purposes because each of them is an individual for itself. For each client in a bank you have to create his own account (you cant share this informations between more clients) the performance part means that if you have a lot of these "individuals" you are going to end up with a lot of them which first of all can fill up your memmory and secondly you will lose a lot of time for the creation of each of them. – Ivan Crojach Karačić Dec 19 '11 at 11:36
    
@Ivan: Thank you. When I first read it I kept thinking about my data model and did I kept thinking of value objects as reference object (i.e not immutable) which is something I should not do in DDD. – JD01 Dec 19 '11 at 12:43

The key property of a Value Object it that it has no identity. It is defined only by it's attributes, and any other instance with identical attribute values can be substituted.

Los Techies had a good explanation on their blog a while back, and it has been asked on StackOverflow.

share|improve this answer

Here is the best analogy that i've been able to "teach" to my co-workers when wanting to work on DDD with Value Objects.

Everytime you think of a Value Object, think of DateTime object in .Net.

For example, when you have a DateTime in your object, and you persist that object, you are only saving a string representation of the date and time in question. It can also be formatted to satisfy certain locales (month-day or day-month for example).

Yet, the DateTime object is so sophisticated internally. They have multiple members to store different values (day, month, year, hour, minute, seconds, milliseconds) so that they can do operations like .AddDay(2) which basically takes the day field, adds a 2 to it and return a brand new DateTime object with the new addition. So, you really never modify the DateTime object. You create a new one everytime you use one of their methods.

Same for your custom value objects... Say, CreditCard... let's look an example.

We want to store credit card information for an user. In our domain, we don't need to keep track of the Creditcard. So, the first thing that we may be tempted to do is to create 4 fields.

string CreditCardNumber {get;set;}
string CreditCardExpiration {get;set;}
string CreditCardType {get;set;}
string CreditCardSecurityCode {get;set;}

Now say that we have these field in our AggregareRoot/Entity. If we want to 'parse' our ExpirationDate to a miningful DateTime object (07/18 to 07/01/2018) for validation purposes, now we need to add that logic to our AR/Entity. You may think... "that's ok" but it is not, because our AR/Entities should be focused on the problem that they solve, not validating credit card expiration dates. That's more ancillary work.

Imagine if DateTime didn't have all those functionalities of Date and Time manipulation and you need to implement all of that in your class, does it sound right? Of course not.

So, in our example we create a CreditCard class

public class CreditCard: ValueObject

then we transfer all of those fields into this class (you can remove the CreditCard prefix). Now you have a lot of power in your hands. You can create as many validation methods as you want: checksum validation, expiration date validation and parsing, actually validate that the credit card type matches its number sequence (Mastercard starts with 54 if I am not mistaken)... I mean, you can add SO MUCH features to your CreditCard class without polluting your AR/Entity. You can create your own "format" to persist this info if you want. Say that you override your .ToString() method and format it as "MC 5474 3434 8383 4848 07/18". Or you can configure your ORM to map to the individual read only properties for those values.

How do you use it effectively? Simple. Say that you have a PaymentMethod class that is an Aggregate Root. You want to keep track of that payment method because it will be used to make payments, so maybe you want to have a payment history linked to this class.

Inside all you need to do is add a CreditCard value object...

public CreditCard BusinessCard {get;}

Now in one of the methods of your AR... say,

private void Enable()
{
    this.IsEnabled = BusinessCard.IsValid();
}

You see? I moved the logic of validating the card into the value object. And guess what? Can be reused!!! You can actually share value objects.

I hope this helps!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.