所以说我在我的应用程序中有两个依赖关系,一个pub pub子系统的连接和一个到数据库的连接。我可以这样做斯卡拉蛋糕模式 - 我可以有多层蛋糕?
trait DB {
def lookup(query:String):String
}
trait PubSub {
def subscribe(key:String, callback:String => Any)
}
然后我可以写我的逻辑就像
trait Functionality { this:DB with PubSub =>
def doSomething() {
val key = lookup("get key")
subscribe(key, data => println(data))
}
}
,然后我的应用程序可以像
object Awesome extends App {
object repository extends Functionality with DB with PubSub {
def lookup(query:String) = "some key"
def subscribe(key:String, callback:String => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key) ; Thread.Sleep(1000) } }
}
}
repository.doSomething()
}
和一切都很好,好世界。
但是如果我想要连接到在同一应用程序中共享相同数据库实现的两个pub子系统呢?
我要像做
object Awesome2 extends App {
object repository extends DB {
def lookup(query: String): String = "some other key"
object connection1 extends Functionality with PubSub with DB {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toUpperCase) ; Thread.sleep(1000) } }
}
}
object connection2 extends Functionality with PubSub with DB {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toLowerCase) ; Thread.sleep(1000) } }
}
}
}
}
其中蛋糕的第二层中的对象(隐式?)从母公司层面的DB实现啜。
但Scala编译器告诉我
error: object creation impossible, since method lookup in trait DB of type (query:String) String is not defined
object connection2 extends Functionality with PubSub with DB {
如果我做以下,然后它做什么,我想
object Awesome3 extends App {
object repository extends DB {
override def lookup(query: String): String = "some other key"
object connection1 extends Functionality with PubSub with DB {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toUpperCase) ; Thread.sleep(1000) } }
}
def lookup(query: String): String = repository.lookup(query)
}
object connection2 extends Functionality with PubSub with DB {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toLowerCase) ; Thread.sleep(1000) } }
}
def lookup(query: String): String = repository.lookup(query)
}
}
repository.connection1.doSomething()
repository.connection2.doSomething()
}
但这是一种凌乱
我可以添加这个特质
trait DB_Base extends DB {
private val db:DB = this
trait DB_Layer extends DB {
def lookup(query:String):String = db.lookup(query)
}
}
然后下面的作品
object Awesome4 extends App {
object repository extends DB_Base {
override def lookup(query: String): String = "some other key"
object connection1 extends Functionality with PubSub with DB_Layer {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toUpperCase) ; Thread.sleep(1000) } }
}
}
object connection2 extends Functionality with PubSub with DB_Layer {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toLowerCase) ; Thread.sleep(1000) } }
}
}
}
repository.connection1.doSomething()
repository.connection2.doSomething()
}
所以现在我有两层。我如何得到三个?我觉得我失去了情节。
蛋糕热量高,血糖负荷高...你有没有看过蛋糕中的成分列表?喜欢简单的天然食物。也就是说,最多只有一层蛋糕,并且使用def来指出所需的任何资源,否则这些资源都需要结块。(这是一个评论,因为它实际上不是解决问题的方法,只是一个建议它会变得笨拙。)删除'扩展DB_Base'并添加'{dbbase =>'并且用'DB_Layer'删除'并添加'def dbLayer = dbbase'或者其他一些代码就可以得到一个明确但紧凑的选择。 – 2012-04-20 17:21:02
感谢雷克斯。我对你的评论感到困惑。首先,'{dbbase =>'完全是做什么的?我不熟悉那种语法。第二,结果看起来不像“Awesome3”吗? – dvmlls 2012-04-20 18:11:50
@RexKerr是对的,但我没有看到你如何在没有附加图层的情况下滚动你自己的Cake DI(因为OP似乎在做)。例如,假设你想烘烤一些DAO蛋糕。您将需要处理数据库连接(生产,阶段,测试),连接类型(JNDI,JDBC)以及用于实现DAO的DAO合同。正如我们可以看到的OP所呈现的那样,模式变得复杂,导致很多头部划伤;-)再次,不确定如何在Scala中做蛋糕DI,而不会掉入兔子洞 – virtualeyes 2012-04-20 18:26:46