1

I am seeing this example in the Microsoft documentation:

enter image description here

Here we can see how OrderItem has a reference to the ID of the product, it is the first option that sure people uses to think, me too.

But I was thinking about this and I was thinking, why isn't OrderItem a value object?

If I use the ID of the product, I have the problem that if after I accepted the order and the description of the product is changed, I will see the new description. So if I want to keep the description that it had when I accepted the order, I can't do in this way.

So I was thinking that perhaps in this case it would be better a value object product, that it will have three properties reference, description and provider. I don't need more for an order item. In this way, the information will be store in a columns of the order line table, and then I will can prevent to modify it if the order is accepted.

Perhaps the example is simply to try to be more clear, but really all the examples that I have seen about order and items are in this way, to use the ID of the product.

So in summary, what are the advantages to use the ID and what are the advantages of the value object?

2
  • So, if you look closely at the OrderItem object, you'll notice that it has the Price property, and some other properties that are not shown. This means that it's not pulling the price from the product, but that it stores its own copy - specifically, it's the price at the time the order was made, exactly because of what you described (price could change). So you can imagine that it probably has some other "cached" properties as well, like maybe description. It's just referencing the product, so that that there's a link to the source product entity. 1/2 Commented Sep 30, 2022 at 21:42
  • As for why OrderItem isn't designed as a value object - I don't know. You could make it either way, depending on your needs. An entity is something that maintains the same conceptual identity across different runs of your application (or even across different applications), so maybe the application in MS's example needs to treat OrderItems that way for some reason. But, it's up to you (the designer(s)) to choose. 2/2 Commented Sep 30, 2022 at 21:42

3 Answers 3

2

What you're after is called immutability. Value objects do not have a monopoly on immutability. Sometimes things are immutable by policy. For example:

OrderItem.Price 

Now sure Product.Price might change. But here sits OrderItem.Price saying we don't care because the price for this particular order was set when it was ordered.

You might notice there's also a ... below price saying you can nail down other fields like that as well. Just because you have a link to the current product info doesn't mean everything is editable. We can simply remember what it was when it was ordered and know that's what's legally binding.

Yes you can insist on making a value object out of it to enforce immutability. But if you can enforce some simple policy rules you can do it this way as well.

So many cats to skin. So little time.

5
  • 1
    I think the problem here is that the OP is conflating the immutable semantics of an OrderItem (semantics which, among other things, improve reasoning when using multiple threads) with the fact that they can achieve the same result by simply storing the description of the item with the OrderItem record, just as you have done with OrderItem.Price. Commented Sep 30, 2022 at 19:56
  • In other words, this is a database design problem, not a "value-type object" problem. Commented Sep 30, 2022 at 19:58
  • @RobertHarvey I'm intentionally avoiding declaring that the problem must be solved in the one true way specifically because I know how many flavors that propaganda comes in. Using a database or not is simply an implementation detail. All we owe them is fulfilled requirements. Commented Sep 30, 2022 at 20:08
  • The OP has presented a database diagram. It's thinly-disguised as DDD aggregates, but it's a diagram of an actual database. If it walks like a duck... Commented Sep 30, 2022 at 20:15
  • @RobertHarvey Yes. It's trying to map one idea onto the other. And the OP is questioning why doesn't immutability imply value object. The problem is that value object implies immutability. The implication arrow wont help you if you point it in the wrong direction. = Commented Sep 30, 2022 at 20:27
1

The simple answer is that a Product is generally too complex an object to represent as a value.

Not sure what you mean by reference. Obviously you wont have a ProductId anymore if its a value object.

Description is subject to arbitrary change, spelling mistakes, corrections, multiple languages etc. Also you will have different products with the same description. ie different models or manufacturers or years of manufacture etc

Provider, only some combinations of product and provider are going to be valid. how are you going to know which?

Then we are going to have a whole bunch of other data, you probably have either a sub or over product to represent multiple colours of the same item, sizes, base price, stock levels, tags for searching, pictures etc etc

Value types work for things which generally only need a single field to completely define them. Dates, colours etc

0

A value object doesn't prevent someone from modifying the database — what if someone changes an Order or OrderItem?

Well, you say, that would be silly, we need to have some discipline around changing things arbitrarily.

Having a discipline or protocol around how the data is used is important.  Changes should be allowed to existing products in the database only if they are meant to supersede/correct old information.  A new version of a product should probably get its own new product id.  Products that are discontinued should be marked that way and remain in the product table rather than begin deleted, which would make it impossible to view older orders.

So, as some discipline is required in all cases, why not have a sensible one around product management?

Capturing additional information in the OrderItem won't necessarily hurt, but moving to a value object — removing the product ID from the OrderItem — would be error prone and inefficient.

You're also showing that your view of the world is purchasing, ordering and customer relations, while someone else controls products — meaning you feel that you cannot rely on them, for example, to have any discipline about deleting product id's that you need for OrderItems.  You should make your requirements known to the other responsible parties in the company — that you need stable product id's and descriptions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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