2

为什么每个人都使用这种形式的定义:

trait UserServiceComponent {
  def userService: UserService
  trait UserService {
    def findAll: List[User]
    def save(user: User)
  }
}

取而代之的是:

trait UserService {
  def findAll: List[User]
  def save(user: User)
}

trait UserServiceComponent {
  def userService: UserService
}

第二种方法似乎更通用,因为 UserService 特征未绑定到特定的组件实例。

有什么我想念的吗?

编辑:通过“更通用”,我的意思是你可以做这样的事情(将两个具有不同 impl. 的蛋糕混合成一个):

object Program extends App with UserServiceComponent with ProductServiceComponent  {
    object Cake1 extends UserServiceComponentImpl with DatabaseComponent1Impl {
    }
    object Cake2 extends ProductServiceComponentImpl with DatabaseComponent2Impl {
    }

    def userService = Cake1.userService
    def productService = Cake2.productService
}

// def
trait DatabaseComponent{
}

trait UserService {
}

trait UserServiceComponent {
  def userService: UserService
}

trait ProductService {
}

trait ProductServiceComponent {
  def productService: ProductService
}

// impl
trait DatabaseComponent1Impl extends DatabaseComponent {
}

trait DatabaseComponent2Impl extends DatabaseComponent {
}

trait UserServiceComponentImpl extends UserServiceComponent {
    self:DatabaseComponent =>

    def userService = new UserService {}
}

trait ProductServiceComponentImpl extends ProductServiceComponent {
    self:DatabaseComponent =>

    def productService = new ProductService {}
}

如果您将 UserService 定义为嵌套特征,那么您将得到一个异常:类型不匹配;找到:Program.Cake1.UserService,需要:Program.UserService

4

2 回答 2

3

在您的第二次构造中,全局命名空间的人口无缘无故地翻了一番。使用经典的 Cake 构造,一个组件是自包含的,它只将一个名称注入到全局命名空间中。

在任何一种情况下,组件的特性(此处trait UserService)都是同样可用的,无论是构造为经典 Cake 还是您的替代方案。也就是说,您的替代方案绝不是“更普遍的”。

于 2014-03-23T21:47:55.330 回答
1

Randall Schulz 的回答是绝对正确的。我只想补充一点,有时第二种形式(带有顶级UserService)是不可避免的。例如,当您必须将组件从“外部”蛋糕传递到“内部”蛋糕时:

trait ExampleComponent {
    def example: Example
}

trait Example {
    def doSomething()
}

trait DefaultExampleComponent {
    override val example = new Example {
        // ...
    }
}

trait SomeOtherComponent { self: ExampleComponent =>
    object InnerCake extends ExampleComponent {
        override def example = self.example
    }
}

object TopLevelCake extends DefaultExampleComponent with SomeOtherComponent

如果Example是 的内在特征ExampleComponent,则赋值

override def example = self.example

不可能,因为self.example有 typeSomeOtherComponent.this.type#ExampleInnerCake.example应该是 type this.type#Example

于 2014-03-24T07:54:35.867 回答