Smart Constructors in Scala
Ideally, all the instances of a class should make sense. In the real world we cannot have “4.5” as an integer for example, so why should we allow that in our programs?
Smart Constructors is a technique to restrict the instances of a class that can be created to those that follow a set of rules. That means that when the constructor is called the call will not always succeed. Scala is a great language for this approach, as we can make the constructor return an Option
or an Either
and use that in the rest of our application.
Although the idea is really straightforward, implementing this functionality is kind of tricky an, i would say, a bit counter intuitive. While discussing it at Twilio the approach of Mike Girkin coming “From amazing Rob Norris gist” really stood up.
Let’s see an example with a simple class Month
that has a single parameter, number
Important points here:
- Month is a
sealed abstract private case class
. Not bad. Everything is done through the companion object. - The only way to create an instance of class
Month
is throughMonth.fromInt
- Methods
copy
andapply
are not generated because class is declaredabstract
- It is not possible to do
new Month(13) {}
outside of the source file where it is defined because it issealed
- Equality still works
- Pattern matching and deconstruction still works
In the result we have a class which can be instantiated through the only method. It is impossible to have Month(13)
anywhere in the code, and we are guaranteed to have valid month number when using an instance of Month.