Scala 工厂模式 return 具体 class 取决于泛型

Scala Factory Pattern return the concrete class depending on the generic type

我使用带有泛型的工厂模式。这个想法是根据 A 的类型创建正确的实现(BlockType1ImplBlockType2Impl),这是一种情况 class( BlockchainType1BlockchainType2).我没有设置任何 Type Bounds 约束。

代码

上查看具有泛型类型的 apply 方法后

trait BlockTypeFactory[A]{

  def findTransactions( blocks: Seq[A], address: String): Seq[TransactionResponse]

}


object BlockTypeFactory{
  // I want this method to return the correct implementations 
  def getBlockExplorer[A](blockType: A): BlockTypeFactory[A] = {
    blockType match {
      case type1: BlockchainType1 => new BlockTypeFactory[BlockchainType1](new BlockType1Impl)
    // error : Expression of type BlockTypeFactory[BlockType1Impl] doesn't conform with the expected type BlockTypeFactory[A]
      case type2: BlockchainType2 => new BlockType2Impl
    }
  }

def apply[A](implicit ev: BlockTypeFactory[A],blockType: A):BlockTypeFactory[A] = ev

}

但是我收到有关预期类型的​​错误到底哪里错了?

其他classes

class BlockType1Impl extends BlockTypeFactory[BlockchainType1]

class BlockType2Impl extends BlockTypeFactory[BlockchainType2]

case class BlockchainType1(...)
case class BlockchainType2(...)

您的代码不起作用,因为编译器不知道从哪里获取 BlockTypeFactory 的隐式实例。

为了实现您的目标,您可以使用类型 Classes。

这种方式是可扩展的,如果你愿意,你可以为每个 class 拥有多个工厂(你需要使用隐式作用域)并且你可以为某些类型定义标准工厂。

您可以在 BlockTypeFactory 对象中编写您的案例 classes 的隐式实例,但这是通常完成的方式。

// your type class
trait BlockTypeFactory[A] {
  def create:A
} 

case class BlockchainType1()

object BlockchainType1 {
  // type 1 impl
  implicit val factory:BlockTypeFactory[BlockchainType1] = new BlockTypeFactory[BlockchainType1] {
    def create: BlockchainType1 = BlockchainType1()
  }
}

case class BlockchainType2()

object BlockchainType2 {
  // type 2 impl
  implicit val factory:BlockTypeFactory[BlockchainType2] = new BlockTypeFactory[BlockchainType2] {
    def create: BlockchainType2 = BlockchainType2()
  }
}

object BlockTypeFactory {

  // get factory
  def apply[A:BlockTypeFactory]:BlockTypeFactory[A] = implicitly[BlockTypeFactory[A]]

  // or create
  def create[A:BlockTypeFactory]:A = implicitly[BlockTypeFactory[A]].create

}

val instance1 = BlockTypeFactory[BlockchainType1].create

val instance2 = BlockTypeFactory.create[BlockchainType2]

此模式称为类型 Class,它用于获得临时多态性。在您的示例中,您需要为 BlockTypeFactory 上定义的每个 class 使用多态方法 findTransactions。