I would like to construct my domain model using immutable objects only. But I also want to use traits with val fields and move some functionality to traits. Please look at the f
You cleanest solution is probably to drop some implementation logic from Versionable
, and push it down the type stack to a case class (where the copy
method will be available to you). Give the version property a default value to complete the design.
trait Versioned {
def version : Int
def nextVersion = version + 1
}
case class Customer(name: String, version : Int = 0) extends Versioned {
def withName(newName: String) = copy(name = newName, version = nextVersion)
}
If you want, you can also define a type alias somewhere for the version numbering:
type Version = Int
val initialVersion = 0
trait Versioned {
def version : Version
def nextVersion = version + 1
}
case class Customer(name: String, version : Version = initialVersion)
extends Versioned {
def withName(newName: String) = copy(name = newName, version = nextVersion)
}