I have the following design issue:
/**
* Those 2 traits are the public API
*/
trait Box {
def include(t: Token): Box
}
trait Token
/**
* Implementation classes
*/
case class BoxImpl(id: Int) extends Box {
/**
* the implementation of this method depends on the implementation
* of the Token trait
* TODO: REMOVE asInstanceOf
*/
def include(t: Token) = BoxImpl(t.asInstanceOf[TokenImpl].id + id)
}
case class TokenImpl(id: Int) extends Token
// use case
val b: Box = new BoxImpl(3)
val o: Token = new TokenImpl(4)
// == BoxImpl(7)
b.include(o)
In the code above, I don’t want to expose id in the public API (not even set it as private[myproject] because that would still include circular dependencies in my project).
What would be the way to leave the public API intact while having the implementation classes having some visibility to each other (without the ugly cast)?
Type param or member:
There’s lots of ways to slice and dice it, hence the cake pattern, the proverbial piece of cake: