首页 文章

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

提问于
浏览
1

我有一个测试,当我迭代 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 回答

  • 2

    两种可能的方式 . 首先,使用 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
    }
    
  • 3

    你的问题在于这一行:

    val immutableMapFactory = scala.collection.immutable.Map
    

    这使得 immutableMapFactory 等于单例对象 Map . ListMap (单例)不是 Map (单例)的子类,因此后续覆盖失败 .

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

    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] _
    }
    

相关问题