Question

I have some entities and some value objects that need to record the moment they were made. Now I read that a value object is a collection of properties with its own set of rules, and two value objects with the same properties are indistinguishable.

Now, I'm probably going to use the standard C# DateTime data type for this, and I don't really know how it is implemented internally (might just be a Unix timestamp, which as a primitive should be a property, but if they have a solution to the year 2038 issue that involves multiple properties in some relation with each other, it would be more complicated).

I think that what makes the difference is that although a timestamp has its own set of rules (e.g. "35th of January" is no valid date), I am not going to be enforcing those rules; the language itself will. The date is always created internally; I'm never parsing anything user-submitted into a date.

So I am leaning towards a timestamp being a property. But then I started thinking: can I apply that rule to any data type which has its rules defined outside my application? For example, an image file. I am not in charge of having it be structured correctly according to the JPEG specification; the language will do that. I could have restrictions on file size, but similarly an entity could have restrictions on the length of one of its strings and I don't see that being made into a value object for just that reason, though I could be wrong on that.

And what if there is a bespoke set of rules for a data type, e.g. an invoice, that the company I work with already implemented elsewhere and I am importing as a library? That could be as complicated a data type as it gets.

So, coherently:

  • Is a timestamp a value object or a property of one?
  • What makes the difference between value objects and properties? Is it a locally defined set of rules, or is it something else?

And even more concretely; I am choosing between these two models (which I understand are to correspond more or less directly with my actual code):

Version 1:

version 1

Version 2:

version 2

Was it helpful?

Solution

A value object is an object that has no identity but is fully defined by its value. A timestamp fully fits that description, and so does an integer and a string.

At the same time, a timestamp can also be a property of a larger object. It is not a matter of choosing between either a value object or an attribute, because it is very normal for value objects to be attributes as well.

As for how you would draw it in an UML diagram, that depends entirely on the information you want to show. As a rule of thumb, I would draw a value object only with its own (stereotyped) class box, as you did in version 2, only when the internal structure of the value object is relevant for the audience of the diagram. Otherwise, just show it as an attribute, or even leave it out completely if the existence of the attribute is not relevant for the audience of the diagram.

OTHER TIPS

A timestamp is a value object: it has no identity and is solely defined by its value components.

In your case you could use a built-in type or go for your own value-type (eg a C# struct).

A value object can be a property of a larger object. Especially if it’s a value-type (There could be some subtle differences if your language would not support value types, but this is not the case with C#).

So both affirmations are not mutually exclusive and it’s more about built-in vs custom type than value vs property.

Is a timestamp a value object or a property of one?

This is up to you. It can even be both. Value objects can be composed of other value objects.

To be clear though, giving a primitive an useful name does not make it a Value Object:

class ActiveState
    int timestamp <== A property that is not a value object (not an object at all)

class ActiveState (Value object)
    Timestamp t <== A value object that's a property on the value object, ActiveState

class Timestamp (Value object)
    int ts (property)

All classes above are Value Object. You don't care which one you get and can use them interchangeably.

However, I think the real confusion here involves Value Objects vs Entities

From Domain Driven Design by Eric Evans, pg 99:

When you care only about the attributes 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. Don't give it any identity and avoid the design complexities necessary to maintain ENTITIES.

The second you slap an "Id" on ActiveState, it's not a Value Object. It's an Entity.

Whether or not something is an Entity or a Value Object depends on how it is being used. For example, a Tire for your car is likely a Value Object to you (you don't care which one you're getting). However, a research team that is tracking the performance of tires individually will probably care which one is which. So, to them each tire will need an unique Identity that they can track, thus making it an Entity.

Licensed under: CC-BY-SA with attribution
scroll top