DDD, how do you change a ValueObject?

2.9k Views Asked by At

The question refers to a situation in which you have to update/delete a valueobject.

Consider this situation.

You have an Order and you have Products and Products have ProductItems. Where ProductItem is a ValueObject. If you would have to update the list of productItems in Product (let's say update the quantity), how would you do it? How will you identify the exact ProductItem that requires the update ?

This is from the perspective or an OrderingContext, there should be a backing context where you have ProductItem stock and ProductItem pricing (InventoryContext), context where a ProductItem is more then just a ValueObject, but since we are under the OrderingContext, how would you update a ProductItem if you don't have a way to identify it?

2

There are 2 best solutions below

0
On BEST ANSWER

You identify the Value object in a list by whatever means you need, there is not rule regarding that.

For example, in this case, one way to identify it is to use it's numeric index from the list. If you need something more stable (i.e. that works also in case of items reordering) you can have GUIDs instead of numeric indexes, in languages that support this. For example, PHP lets you use strings for array access and GUIDs can be converted to strings before use in an array lookup.

The important rule to remember about Value objects: they should be immutable, that is, if you need to update one then you replace it with another instance.

0
On

The idea behind the ValueObject is that it is immutable. When you want to change a value object you don't do that property by property, you change the entire thing.

public class MyVo
{
   public int MyProp1 { get; }
   public int MyProp2 { get; }
   public int MyProp3 { get; }

   private MyVo()
   {
   }
   public MyVo(int myProp1)
   {
      MyProp1 = myProp1
   }
   private MyVo(int myProp1, int myProp2, int myProp3)
     :this(myProp1)
   {
      MyProp2 = myProp2
      MyProp3 = myProp3
   }

   public MyVo MyMeaningfulNameMethod(int prop2, int prop3)
      => new MyVo(this.MyProp1, prop2, prop3)
}