Hi, I’ve just started studying Scala and I have some questions regarding how to construct domain models.
I have this case class:
case class Client (id: UUID, name: String, isActive: Boolean)
I’m want to follow the idea of making illegal states unrepresentable, so I created a phantom type for id
and specific types for isActive
. That was the result:
sealed trait ClientState
case object Active extends ClientState
case object Inactive extends ClientState
case class Client (id: ID[Client], name: String, isActive: ClientState)
This is much better. But let’s say the name
cannot be null or greater than 50. The above implementation is still not enough. I don’t know what is the recommended way to solve this in Scala. So, I decided to do the same thing I would do in F#, which is by creating a String50 type. That was the result:
class String50 private (val value: String) extends AnyVal {
override def toString: String = value
}
// USING SCALAZ FOR VALIDATION
object String50 {
def apply(value: String): ValidationNel[String, String50] = {
if (value == null || value.isEmpty) {
"$property cannot be empty".failureNel[String50]
} else if (value.length > 50) {
"$property cannot be longer than 50".failureNel[String50]
} else {
new String50(value).successNel[String]
}
}
}
Then, I updated the Client
with String50
and created a create
function:
// NOTE THAT I ADDED "NAME2" JUST TO TEST THE APPLICATIVE PATTERN
case class Client (id: ID[Client], name: String50, name2: String50, isActive: ClientState)
object Client {
import Scalaz._
def validateName(name: String): ValidationNel[String, String50] = {
// transform possible validation error
// replace "$property" with "Name" ????
String50(name)
}
def validateName2(name2: String): ValidationNel[String, String50] = {
// transform possible validation error
// replace "$property" with "Name 2" ????
String50(name2)
}
def create(name: String, name2: String): ValidationNel[String, Client] = {
(
validateName(name) |@|
validateName2(name2)
) { (n1, n2) =>
Client(ID(), n1, n2, Active)
}
}
}
This is what I have so far.
Am I on the right track? Is there a nice way to format the error messages without pattern matching?
I also would be glad if someone gives me a link of the source-code of a DDD application in Scala. I just found some small incomplete examples on GitHub that didn’t help at all =/
Thank you!