代码之家  ›  专栏  ›  技术社区  ›  Raymond Chenon

Scala工厂模式根据泛型类型返回具体类

  •  2
  • Raymond Chenon  · 技术社区  · 6 年前

    我使用工厂模式和泛型。其目的是创建正确的实现( BlockType1Impl BlockType2Impl )取决于 A 这是一个案例类( BlockchainType1 BlockchainType2 ). 我没有设置任何类型边界约束。

    代码

    看了之后 this example 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
    
    }
    

    但我知道 . 到底怎么了?

    其他类

    class BlockType1Impl extends BlockTypeFactory[BlockchainType1]
    
    class BlockType2Impl extends BlockTypeFactory[BlockchainType2]
    
    case class BlockchainType1(...)
    case class BlockchainType2(...)
    

    fhdfjfh公司

    1 回复  |  直到 6 年前
        1
  •  3
  •   Sebastian Celestino    6 年前

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

    为了达到你的目标,你可以使用类型类。

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

    您可以在BlockTypeFactory对象中编写case类的隐式实例,但通常是这样做的。

    // 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]