如何使用Scala的蛋糕图案来实现机器人腿?

时间:2012-01-27 14:52:36

标签: scala dependency-injection guice cake-pattern robot-legs-problem

我的开发广泛使用机器人腿绑定问题。我在Guice中知道how to solve itPrivateModule,但目前尚不清楚如何使用Scala的蛋糕模式。

有人可以解释一下如何做到这一点,理想情况下,根据Jonas Boner在blog post结束时的咖啡示例的具体例子?也许有一个可以为左侧和右侧配置的加热器,注入方向和def isRightSide

1 个答案:

答案 0 :(得分:3)

蛋糕模式不能以原始形式解决此问题。你有several choices如何处理它。我更喜欢的解决方案是通过使用适当的参数调用其构造函数来创建每个“机器人腿” - code显示比单词更好。

我认为上面引用的答案更具可读性,但如果您已经熟悉Jonas的示例,那么您可以通过以下方式配置Warmer:

// =======================
// service interfaces
trait OnOffDeviceComponent {
  val onOff: OnOffDevice
  trait OnOffDevice {
    def on: Unit
    def off: Unit
  }
}
trait SensorDeviceComponent {
  val sensor: SensorDevice
  trait SensorDevice {
    def isCoffeePresent: Boolean
  }
}

// =======================
// service implementations
trait OnOffDeviceComponentImpl extends OnOffDeviceComponent {
  class Heater extends OnOffDevice {
    def on = println("heater.on")
    def off = println("heater.off")
  }
}
trait SensorDeviceComponentImpl extends SensorDeviceComponent {
  class PotSensor extends SensorDevice {
    def isCoffeePresent = true
  }
}
// =======================
// service declaring two dependencies that it wants injected
trait WarmerComponentImpl {
  this: SensorDeviceComponent with OnOffDeviceComponent =>

  // Note: Warmer's orientation is injected by constructor.
  // In the original Cake some mixed-in val/def would be used
  class Warmer(rightSide: Boolean) {
    def isRightSide = rightSide
    def trigger = {
      if (sensor.isCoffeePresent) onOff.on
      else onOff.off
    }
  }
}

// =======================
// instantiate the services in a module
object ComponentRegistry extends
  OnOffDeviceComponentImpl with
  SensorDeviceComponentImpl with
  WarmerComponentImpl {

  val onOff = new Heater
  val sensor = new PotSensor
  // Note: now we need to parametrize each particular Warmer
  // with its desired orientation
  val leftWarmer = new Warmer(rightSide = false)
  val rightWarmer = new Warmer(rightSide = true)
}

// =======================
val leftWarmer = ComponentRegistry.leftWarmer
leftWarmer.trigger