给定以下FooService
scala> trait FooService {
| def go: Int
| }
defined trait FooService还有一个MainService,它代表一个main方法。
scala> trait MainService extends FooService {
| def f = go + 42
| }
defined trait MainServiceFooService可以有一个假的(用于测试)和一个真实的实现(例如命中DB ):
scala> object FakeService extends FooService {
| def go = 10
| }
defined object FakeService
scala> object RealService extends FooService {
| def go = 55 // in reality, let's say it hit the DB and got a value
| }
defined object RealService在我看来,添加一个"runner“类/特征,即运行sbt run将导致该类的执行,将是可行的。它看起来是这样的:
scala> class Main extends MainService {
| override def go = RealService.go
| }
defined class Main我也可以定义一个测试:
scala> class Test extends MainService {
| override def go = FakeService.go
| }
defined class Test我不确定这是否是定义真实MainService与测试a的惯用方式。请让我知道。
发布于 2015-07-04 22:59:28
您可以使用流行的蛋糕模式,这种模式也被称为"Scala方式“来进行依赖注入。
Jon对此做了一个很好的blog post演练(他还列出了一些替代方案)。
首先,FooService的特性
trait FooServiceComponent {
val fooService: FooService
trait FooService {
def go: Int
}
}也就是说,我们需要两件事: 1.实际的对象,2.它的定义/实现。这两个名称空间都在一起。好的。以下是Fake和Real版本:
trait FakeService extends FooServiceComponent {
class FakeService extends FooService {
def go = 10
}
}
trait RealService extends FooServiceComponent {
class RealService extends FooService {
def go = 55
}
}现在,对于MainService
trait MainServiceComponent { this: FooServiceComponent =>
val mainService: MainService
class MainService extends FooService {
def f = go + 42
def go = fooService.go // using fooService
}
}请注意自输入this: FooServiceComponent,这是MainServiceComponent依赖于FooServiceComponent的一种Scala方式。如果您试图在不混入任何FooServiceComponent的情况下实例化MainServiceComponent,那么您将得到一个编译时错误。好的。:)
现在,让我们创建具有不同特征的Test和Main对象:
object Test extends MainServiceComponent with FakeService {
val mainService = new MainService()
val fooService = new FakeService()
}
object Main extends MainServiceComponent with RealService {
val mainService = new MainService()
val fooService = new RealService()
}请注意,由于名称空间的原因,不能在Main中访问FakeService,因为它没有混合在一起。好的。:)还要注意,直到此时才对类的任何实例化进行延迟,这很方便,因为您可以很容易地使用注册表或模拟库在一个地方替换它们。
结果:
println(Test.mainService.f) // -> 52
println(Main.mainService.f) // -> 97我希望这能帮到你。
https://stackoverflow.com/questions/31215914
复制相似问题