有些问题与这个问题有些相关,但它们看起来并不合适。
我正在使用Cake模式在生产代码中放置“Storage”系统,并将Stub存储系统用于测试目的。这一切都很棒,但是有一个类在原始类中实例化,也需要混合使用这个存根系统。由于它隐藏在实现中,我无法访问它。
事情看起来像这样:
class Main { this: Storage =>
...
val used = Used(...)
...
}
class Used { this: Storage =>
...
}
在测试“已使用”时,我只是new Used with StubStorage
然后关闭。我曾经对Main
做同样的事情,但那是在它使用Used
之前。现在Main
对Used
做了一个天真的实例化,我遇到了这个问题。
我想这样试试:
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
。
答案 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 }