Scala 工厂模式 return 具体 class 取决于泛型
Scala Factory Pattern return the concrete class depending on the generic type
我使用带有泛型的工厂模式。这个想法是根据 A
的类型创建正确的实现(BlockType1Impl
或 BlockType2Impl
),这是一种情况 class( BlockchainType1
或 BlockchainType2
).我没有设置任何 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。
我使用带有泛型的工厂模式。这个想法是根据 A
的类型创建正确的实现(BlockType1Impl
或 BlockType2Impl
),这是一种情况 class( BlockchainType1
或 BlockchainType2
).我没有设置任何 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。