加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么使用scala的蛋糕模式而不是抽象字段?

发布时间:2020-12-16 09:47:40 所属栏目:安全 来源:网络整理
导读:我一直在阅读关于在scala通过 cake pattern做依赖注入。我想我明白了,但我一定错过了一些东西,因为我还是看不到它的点!为什么优选通过自我类型而不是仅仅抽象字段来声明依赖性? 给定在Programming Scala中的示例TwitterClientComponent使用蛋糕模式声明
我一直在阅读关于在scala通过 cake pattern做依赖注入。我想我明白了,但我一定错过了一些东西,因为我还是看不到它的点!为什么优选通过自我类型而不是仅仅抽象字段来声明依赖性?

给定在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,new Date)
    if (service.sendTweet(twt)) {
      localCache.saveTweet(twt)
      ui.showTweet(twt)
    }
  }
}

看看实例化时间,这是当DI实际发生(我理解它),我很难看到蛋糕的优势,特别是当你考虑额外的键盘输入你需要做的蛋糕声明(封闭性状)

//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
        }

我肯定我必须缺少一些关于蛋糕的优势!但是,目前我看不出它以任何其他方式声明依赖性(构造函数,抽象字段)。

解决方法

想想如果TwitterService使用TwitterLocalCache会发生什么。如果TwitterService自行输入到TwitterLocalCache,这将会容易得多,因为TwitterService无法访问您声明的val localCache。蛋糕模式(和自我打印)允许我们以更通用和灵活的方式注入(当然,除此之外)。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读