我一直在阅读使用蛋糕模式在scala中进行依赖注入的内容。我认为我已经理解了它,但可能错过了某些东西,因为我仍然看不出其中的重点!为什么通过自身类型声明依赖关系比仅使用抽象字段更可取呢?
在Programming Scala中给出的示例中,TwitterClientComponent
使用蛋糕模式声明依赖关系如下:
//other trait declarations elided for clarity
...
trait TwitterClientComponent {
self: TwitterClientUIComponent with
TwitterLocalCacheComponent with
TwitterServiceComponent =>
val client: TwitterClient
class TwitterClient(val user: TwitterUserProfile) extends Tweeter {
def tweet(msg: String) = {
val twt = new Tweet(user, msg, new Date)
if (service.sendTweet(twt)) {
localCache.saveTweet(twt)
ui.showTweet(twt)
}
}
}
}
这种方式比下面将依赖项声明为抽象字段的方式更好在哪里?
trait TwitterClient(val user: TwitterUserProfile) extends Tweeter {
//abstract fields instead of cake pattern self types
val service: TwitterService
val localCache: TwitterLocalCache
val ui: TwitterClientUI
def tweet(msg: String) = {
val twt = new Tweet(user, msg, new Date)
if (service.sendTweet(twt)) {
localCache.saveTweet(twt)
ui.showTweet(twt)
}
}
}
就实例化时间而言,也就是 DI 实际发生的时候(据我所知),我很难看出 Cake 的优势,尤其是考虑到为了 Cake 声明需要额外键盘输入的内容(包含 trait)。
//Please note, I have stripped out some implementation details from the
//referenced example to clarify the injection of implemented dependencies
//Cake dependencies injected:
trait TextClient
extends TwitterClientComponent
with TwitterClientUIComponent
with TwitterLocalCacheComponent
with TwitterServiceComponent {
// Dependency from TwitterClientComponent:
val client = new TwitterClient
// Dependency from TwitterClientUIComponent:
val ui = new TwitterClientUI
// Dependency from TwitterLocalCacheComponent:
val localCache = new TwitterLocalCache
// Dependency from TwitterServiceComponent
val service = new TwitterService
}
现在再来一次,使用抽象字段,大致相同!:
trait TextClient {
//first of all no need to mixin the components
// Dependency on TwitterClient:
val client = new TwitterClient
// Dependency on TwitterClientUI:
val ui = new TwitterClientUI
// Dependency on TwitterLocalCache:
val localCache = new TwitterLocalCache
// Dependency on TwitterService
val service = new TwitterService
}
我相信自己一定错过了关于蛋糕优越性的某些东西!然而,目前我看不出它提供了什么比以任何其他方式(构造函数、抽象字段)声明依赖性更好的东西。
service
是来自于TwitterServiceComponent
,但我不确定我们如何知道它被命名为service
? - Kevin Meredith