我有以下设计问题:
/**
* 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)
在上面的代码中,我不想在公共API中公开id
(甚至不将其设置为private[myproject]
,因为在我的项目中仍然会包含循环依赖项。)
在让实现类具有彼此可见性的实现类(没有丑陋的演员表)的情况下,保持公共API完整的方法是什么?
答案 0 :(得分:5)
输入param或member:
trait Box {
type T <: Token
def include(t: T): Box
//def include(t: Token): Box
}
trait Token
case class BoxImpl(id: Int) extends Box {
type T = TokenImpl
def include(t: T) = BoxImpl(t.id + id)
/*
def include(t: Token) = t match {
case ti: TokenImpl => BoxImpl(ti.id + id)
case _ => throw new UnsupportedOperationException
}
*/
//def include(t: Token) = BoxImpl(t.asInstanceOf[TokenImpl].id + id)
}
case class TokenImpl(id: Int) extends Token
有很多方法可以切片和切块,因此蛋糕模式,众所周知的蛋糕:
trait Boxer {
type Token <: Tokenable
trait Box {
def include(t: Token): Box
}
trait Tokenable
}
trait Boxed extends Boxer {
type Token = TokenImpl
case class BoxImpl(id: Int) extends Box {
override def include(t: Token) = BoxImpl(t.id + id)
}
case class TokenImpl(id: Int) extends Tokenable
}
trait User { this: Boxer =>
def use(b: Box, t: Token): Box = b.include(t)
}
object Test extends App with Boxed with User {
val b: Box = new BoxImpl(3)
val o: Token = new TokenImpl(4)
println(use(b, o))
}