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

scala – Cake模式:每个实现一个组件,或每个特性一个组件?

发布时间:2020-12-16 09:49:52 所属栏目:安全 来源:网络整理
导读:我正在努力在我的应用程序上使用蛋糕模式. 在网上找到的例子中,例子是基本的,但不涉及更复杂的需求.我想做的事情并不那么花哨:我想在蛋糕模式应用程序中使用相同类型的2个服务,使用不同的实现. trait UserServiceComponent { self: UserRepositoryComponent
我正在努力在我的应用程序上使用蛋糕模式.

在网上找到的例子中,例子是基本的,但不涉及更复杂的需求.我想做的事情并不那么花哨:我想在蛋糕模式应用程序中使用相同类型的2个服务,使用不同的实现.

trait UserServiceComponent {
  self: UserRepositoryComponent =>
  val userService: UserService

  class DefaultUserService extends UserService {
    def getPublicProfile(id: String): Either[Error,User] = userRepository.getPublicProfile(id)
  }

  class AlternativeUserService extends UserService {
    def getPublicProfile(id: String): Either[Error,User] = call webservice here for exemple...
  }
}

trait UserService extends RepositoryDelegator[User] {
  def getPublicProfile(id: String): Either[Error,User]
}

如果我一次使用UserService的一个实现,它工作正常,但如果我在同一时间需要两个实现,我真的不知道如何做到这一点.

我应该创建2个不同的组件吗?每一个都暴露出不同的userService值名称? (defaultUserService / alternativeUserService).使用一个组件进行实现我不知道其他组件在使用名称userService时如何能够知道使用了哪个实现,因为我的应用程序中有2个不同的实现.

顺便说一下,当组件表达对UserRepositoryComponent的依赖时,虽然并非所有实现都需要它,但我觉得只有一个组件对吗有点奇怪?
想象一下,我不想构建需要两种实现的完整应用程序,但是对于测试,我需要仅构建不需要UserRepositoryComponent的AlternativeUserService,因为它不会提供这种依赖关系会很奇怪使用.

有人可以给我一些建议,以便我知道该怎么做?

一种相关的问题:
Cake pattern: how to get all objects of type UserService provided by components

谢谢

解决方法

首先,您应该将UserServiceComponent与UserService的实现分离:

trait UserService extends RepositoryDelegator[User] {
  def getPublicProfile(id: String): Either[Error,User]
}

trait UserServiceComponent {
  val userService: UserService
}

trait DefaultUserServiceComponent extends UserServiceComponent { self: UserRepositoryComponent =>
  protected class DefaultUserService extends UserService {
    def getPublicProfile(id: String): Either[Error,User] = userRepository.getPublicProfile(id)
  }
  val userService: UserService = new DefaultUserService
}

trait AlternativeUserServiceComponent extends UserServiceComponent {
  protected class AlternativeUserService extends UserService {
    def getPublicProfile(id: String): Either[Error,User] = call webservice here for exemple...
  }
  val userService: UserService = new AlternativeUserService
}

如果这看起来很冗长,那就好了.蛋糕图案不是特别简洁.

但请注意它是如何解决您对UserRepositoryComponent具有依赖性的问题,即使实际上并不需要(例如仅使用AlternativeUserService时).

现在,在实例化应用程序时我们所要做的就是混合使用DefaultUserServiceComponent或AlternativeUserServiceComponent.

如果您碰巧需要访问这两个实现,那么您确实应该公开两个userService值名称.事实上,3个名字,如:

> DefaultUserService实现的defaultUserService
> AlternativeUserService实现的alternativeUserService
>任何UserService实现的mainUserService(应用程序在“混合时”选择哪一个).

举例:

trait UserService extends RepositoryDelegator[User] {
  def getPublicProfile(id: String): Either[Error,User]
}

trait MainUserServiceComponent {
  val mainUserService: UserService
}

trait DefaultUserServiceComponent { self: UserRepositoryComponent =>
  protected class DefaultUserService extends UserService {
    def getPublicProfile(id: String): Either[Error,User] = userRepository.getPublicProfile(id)
  }
  val defaultUserService: UserService = new DefaultUserService
}

trait AlternativeUserServiceComponent {
  protected class AlternativeUserService extends UserService {
    def getPublicProfile(id: String): Either[Error,User] = ??? // call webservice here for exemple...
  }
  val alternativeUserService: UserService = new AlternativeUserService
}

然后你可以像这样实例化你的蛋糕:

object MyApp 
  extends MainUserServiceComponent 
  with DefaultUserServiceComponent 
  with AlternativeUserServiceComponent 
  with MyUserRepositoryComponent // Replace with your real UserRepositoryComponent here    
{
  //val userService = defaultUserService
  val mainUserService = alternativeUserService
}

在上面的示例中,明确要访问DefaultUserService的服务会将DefaultUserServiceComponent作为其组件的依赖(对于AlternativeUserService和AlternativeUserServiceComponent也是如此),而只需要一些UserService的服务会将MainUserServiceComponent作为依赖项.您决定“混合时间”服务mainUserService指向哪个(这里,它指向DefaultUserService实现.

(编辑:李大同)

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

    推荐文章
      热点阅读