繁体   English   中英

避免与Cake Pattern名称冲突

[英]Avoid name collision with Cake Pattern

我目前正在使用Cake Pattern来实现一些优化算法。 我经常遇到名字碰撞问题。 例如:

trait Add[T] { this: Foo[T] =>
  def constant: T
  def plus( t1: T, t2: T ): T
  def add( t: T ) = plus( t, constant )
}

trait Mul[T] { this: Bar[T] =>
  def constant: T
  def times( t1: T, t2: T ): T
  def mul( t: T ) = times( t, constant )
}

trait Operations[T] { this: Add[T] with Mul[T] =>
  def neg( t: T ): T
}

这里, constantAddMul特征中定义,但它们的值可能不同。 我可以在名称前加上特征名称,但我觉得它很丑陋( def mulConstant: T )。 有没有更好的方法呢?

据我所知,传统的蛋糕模式通常涉及1层特性嵌套,以便将操作组合在一起。 然后,外层声明实际的“服务”(这里:添加,Mul,操作)而不定义它。

trait AddComponent[T] { this: FooComponent[T] =>
  def addition: Add

  trait Add {
    def constant: T
    def plus( t1: T, t2: T ): T
    def add( t: T ) = plus( t, constant )
  }
}

trait MulComponent[T] { this: BarComponent[T] =>
  def multiplication: Mul

  trait Mul {
    def constant: T
    def times( t1: T, t2: T ): T
    def mul( t: T ) = times( t, constant )
  }
}

trait OperationsComponent[T] { this: Add[T] with Mul[T] =>
  def operations: Operations

  trait Operations {
    def neg( t: T ): T
  }
}

然后,当将“... Component”特征混合在一起时,依赖关系是有线的:

trait IntOperations extends Operation[Int] {
  class IntAdd extends Add { ... }
  class IntMul extends Mul { ... }
}

class MyFooBar extends FooComponent[Int] with BarComponent[Int] with IntOperations {
  lazy val addition = new IntAdd
  lazy val multiplication = new IntMul
  lazy val foo = ...
  lazy val bar = ...
}

这解决了您的特定命名空间问题,但名称冲突(“服务”定义)仍然是传统蛋糕模式的问题。 Daniel Spiewak 发表一篇博客文章 ,演示了如何解决这个问题,但解决方案有自己的一套(巨大的)权衡(参见本演讲 )。

希望有所帮助。

PS而不是类型参数在这里使用抽象类型可能更好

这可能有点不合时宜,而且它不是你问题的直接答案,但是简单地将依赖注入到构造函数中并不容易吗? 每个协作者都有自己的命名空间,因此永远不会发生冲突。 并且对于班级的公共api也没有问题。 然而,仍然难以混合DI和蛋糕模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM