2

Assuming that I want that following Value Object contains always capitalized String value. Is it eligible to do it like this with toUpperCase() in constructor?

class CapitalizedId(value: String) {
    val value: String = value.toUpperCase()
    // getters
    // equals and hashCode
}
Roman T
  • 1,400
  • 5
  • 18
  • 31

2 Answers2

1

In general, I do not see a problem of performing such a simple transformation in a value object's constructor. There should of course be no surprises for the user of a constructor but as the name CapitalizedId already tells you that whatever will be created will be capitalized there is no surprise, from my point of view. I also perform validity checks in constructors to ensure business invariants are adhered.

If you are worried to not perform operations in a constructor or if the operations and validations become too complex you can always provide factory methods instead (or in Kotlin using companion, I guess, not a Kotlin expert) containing all the heavy lifting (think of LocalDateTime.of()) and validation logic and use it somehow like this:

CapitalizedId.of("abc5464g"); 

Note: when implementing a factory method the constructor should be made private in such cases

Andreas Hütter
  • 3,288
  • 1
  • 11
  • 19
  • 1
    Thanks for the great advice regarding the factory methods. I guess I could make then the constructor private or remove it at all. The value object won't be called of course `CapitalizedId` :) But in our ubiquitous language, it's assumed that this value object contains always a capilalized String. – Roman T May 26 '21 at 06:14
  • Yes, thanks for pointing that out, I forgot to mention, making the constructor private should be done additionally in such cases. I will update that in my answer. I don't know the mechanics of Kotlin that well, but just be careful that removing the constructor altogether does not leave you with a default constructor that still allows to initialize the value object and in this case bypassing your business logic for creation and validation. – Andreas Hütter May 26 '21 at 06:19
-1

Is it eligible to do it like this with toUpperCase() in constructor?

Yes, in the sense that what you end up with is still an expression of the ValueObject pattern.

It's not consistent with the idea that initializers should initialize, and not also include other responsibilities. See Misko Hevery 2008.

Will this specific implementation be an expensive mistake? Probably not

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91