Among the different reasons behind having an interface is decoupling – that is the Inversion of Control. According to Uncle Bob’s DIP, the dependency-inversion principle:
a. High-level modules should not depend on low-level modules. Both should depend on abstraction.
b. Abstraction should not depend on details. Details should depend on abstraction.
You are probably aware of this in other cases. But why should there be an interface for a value object?
According to Martin Fowler, one of the purposes of a value object is also to be a place to accomodate any functionality related to that object in future. This indicates a growing object and an interface becomes important as object grows.
You may not want to add the interface at the introduction of a value object due to YAGNI. However, I think it is a right time to introduce the interface as soon as the value object start to contain public methods.
Another case where introducing interface at the introduction of value object can be very useful is, when the value object has to travel through multiple levels of abstractions.
I started a web project recently by having interfaces for all value objects. Later, I thought to remove those interfaces. The very first interface I was to remove was “SimpleHttpResopnse”. It contained http status code and content. This was actually the response generated by controller, which in turn, used use a long abstraction of classes.
Controller >> UseCase >> Responder >> Factory
All had return type “SimpleHttpResopnse”. If it is not an interface, this would be a big refactoring in future if “SimpleHttpResopnse” grows into something big. I don’t think having an interface hurts here.