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

DI在Scala与蛋糕模式

发布时间:2020-12-16 09:07:04 所属栏目:安全 来源:网络整理
导读:这个 article通过Scala的Cake Pattern解释了依赖注入. 我对这种模式的好处的理解是,特征可以与(生产对测试)混合使用静态检查. 在Bonér先生的例子中,他列出了这个完成的(每个例子)代码: UserRepositoryComponent和UserServiceComponent 我根据我的理解添加
这个 article通过Scala的Cake Pattern解释了依赖注入.

我对这种模式的好处的理解是,特征可以与(生产对测试)混合使用静态检查.

在Bonér先生的例子中,他列出了这个完成的(每个例子)代码:

UserRepositoryComponent和UserServiceComponent

我根据我的理解添加了评论.

trait UserRepositoryComponent {
  val userRepository: UserRepository    // stand-alone component

  class UserRepository {      
    ...                      // actual implementation here
  }
} 
trait UserServiceComponent { 
  this: UserRepositoryComponent =>      //Requires a mixed-in UserRepo*Component

  val userService: UserService  

  class UserService {
    ...                      // actual implementation here
  }
}

我的理解是服务依赖于注入存储库组件.

出于生产目的,可以使用以下内容将“生产”存储库组件连接到UserServiceComponent:

object ComponentRegistry extends 
  UserServiceComponent with 
  UserRepositoryComponent 
{
  val userRepository = new UserRepository
  val userService = new UserService
}

如果我们的生产代码想要使用userRepository或userService,那么通过简单导入使用它们的正确方法是什么?

到目前为止,我认为我理解文章的一半,但我不确定如何使用ComponentRegistry对象.

解决方法

你是第一次进入厄运兄弟的面包店:
What are some compelling use cases for dependent method types?

要回答你的问题,使用userService的正确方法是使用另一个特性并将其搞砸:

trait Example { this: UserServiceComponent => 
   def getExampleUser() = userService.getUser("ExampleUser")
}

现在无论这个新特性做什么都没有直接耦合到像ComponentRegistry这样的对象.相反,您的应用程序变为:

object Application extends 
  Example with
  UserServiceComponent with 
  UserRepositoryComponent 
{
  val userRepository = new UserRepository
  val userService = new UserService
}

无论如何,你应该跑到山上,因为如果你真的想要使用蛋糕,你应该做更像这样的事情:

trait UserRepositoryComponent {

  type UserRepository <: UserRepositoryLike

  val userRepository: UserRepository

  trait UserRepositoryLike {
    def getUserOrSomething()
  }

}

trait UserRepositoryComponentImpl extends UserRepositoryComponent {

  type UserRepository = UserRepositoryImpl
  val userRepository = new UserRepositoryImpl

  class UserRepositoryImpl extends UserRepositoryLike {
    override def getUserOrSomething() = ???
  }

}

trait UserServiceComponent {
  this: UserRepositoryComponent =>

  type UserService <: UserServiceLike
  val userService: UserService

  trait UserServiceLike {
    def getUserNameById(id: Int): String
  }

}

trait UserServiceComponentImpl extends UserServiceComponent {
  this: UserRepositoryComponent =>

  type UserService = UserServiceImpl
  val userService = new UserServiceImpl

  class UserServiceImpl extends UserServiceLike {
    override def getUserNameById(id: Int) = userRepository.getUserOrSomething
  }

}

trait Example {
  this: UserServiceComponent =>

  def getExampleUser() = userService.getUserNameById(1)

}

object Application extends
Example with
UserRepositoryComponentImpl with
UserServiceComponentImpl

现在节省一些时间,丢弃蛋糕模式,并做一些事情simple.

(编辑:李大同)

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

    推荐文章
      热点阅读