如何使用Scala中的类型参数声明匿名mixin

时间:2011-05-31 12:13:28

标签: scala

有些问题与这个问题有些相关,但它们看起来并不合适。

我正在使用Cake模式在生产代码中放置“Storage”系统,并将Stub存储系统用于测试目的。这一切都很棒,但是有一个类在原始类中实例化,也需要混合使用这个存根系统。由于它隐藏在实现中,我无法访问它。

事情看起来像这样:

class Main { this: Storage =>
  ...
  val used = Used(...)
  ...
}

class Used { this: Storage =>
  ...
}

在测试“已使用”时,我只是new Used with StubStorage然后关闭。我曾经对Main做同样的事情,但那是在它使用Used之前。现在MainUsed做了一个天真的实例化,我遇到了这个问题。

我想这样试试:

class Main[T <: Storage] { this: T =>
  ...
  val used = Used[T](...)
  ...
}

class Used[T <: Storage] { this: T =>
  ...
}
object Used {
  def apply[T <: Storage](...) = new Used(...) with T
}

但当然这不起作用,因为编译器没有足够的信息来发现T。这有一个神奇的食谱吗?我已经玩过一段时间,看起来很麻烦,标准的OO注射方法实际上不那么麻烦,但我可能会遗漏一些东西。

我已经看过了隐含的工厂概念,但是我无法将其打造成适合mixin的形状。

编辑:公开提出问题的清晰度令人惊讶。 :)我没有按照我原来的意图解决问题,但是对于实际问题有一个简单的解决方案:

trait UsedProvider {
  def createUsed = Used.apply _
}

class Main { this: Storage with UsedProvider =>
  val used = createUsed(...)
}

然后我会在测试中执行以下操作:new Main with StubStorage with StubUsedProvider

1 个答案:

答案 0 :(得分:0)

我还没有解决您的原始问题,但您是否考虑过使用Main的抽象类,并在需要的地方提供used的值?

abstract class Main { this: Storage =>
  val s = "s"
  val used: Used
}

然后像这样实例化:

val main = new Main with StubStorage { val used = new Used(s) with StubStorage }