如何使用伴侣工厂对象作为策略?

时间:2011-10-24 22:36:57

标签: scala scala-collections

我有一个测试,当我迭代Map中的值时因为排序问题而间歇性地失败。

Scala有助于提供ListMap,这会使测试稳定,但会牺牲性能。所以我将ImmutableMapFactory抽象为val并在我的代码中使用它。

class C {
  val immutableMapFactory = scala.collection.immutable.Map

  def func = {
    ...
    immutableMapFactory(pairs :_*)
  }
}

现在我的计划是扩展C并覆盖immutableMapFactory以进行测试

class TestableC extends C {
  override val immutableMapFactory = scala.collection.immutable.ListMap
}

不足为奇,因为ListMapMap的类型不同,所以失败了。我应该如何指定val(或def)的类型,以便我可以在任何需要的地方使用工厂来创建Map?

2 个答案:

答案 0 :(得分:3)

两种可能的方式。首先,使用def和函数,我认为这是一个更好的抽象。

class C {
  def immutableMapFactory[A,B]: ((A,B)*) => Map[A,B] = scala.collection.immutable.Map.apply _
}

class TestableC extends C {
  override def immutableMapFactory[A,B] = scala.collection.immutable.ListMap.apply _
}

其次,使用val和结构类型:

class C {
  val immutableMapFactory: { def apply[A,B](t: (A,B)*): Map[A,B] } = scala.collection.immutable.Map
}

class TestableC extends C {
  override val immutableMapFactory: { def apply[A,B](t: (A,B)*): Map[A,B] } = scala.collection.immutable.ListMap
}

答案 1 :(得分:2)

你的问题在这一行:

val immutableMapFactory = scala.collection.immutable.Map

这使immutableMapFactory等于单例对象MapListMap(单例)Map(单例)的子类,因此后续覆盖失败。

如果您改为从apply获取Map方法,并将其部分应用于形成第一类函数(类型为(A, B)* => immutable.Map[A,B]),则可以使该技术起作用:< / p>

import collection.immutable

class Bip {
  def fac[A,B] = immutable.Map.apply[A,B] _
}

class Bop extends Bip {
  override def fac[A,B] = immutable.ListMap.apply[A,B] _
}