Scala набирает черты разных типов Реализация, сохраняющая ее в Map, не работает - PullRequest
0 голосов
/ 08 июня 2018

Есть ли лучший дизайн для реализации этого сценария?

case class Animal()
case class Dog() extends Animal
case class Cow() extends Animal

trait BasePropertyImpl[T <: Animal] {
  def property1(animal: T): T

  def property2(animal: T): T
}

object DogPropertyImpl extends BasePropertyImpl[Dog] {
  def property1(animal: Dog): Dog = ???

  def property2(animal: Dog): Dog = ???
}

object CowPropertyImpl extends BasePropertyImpl[Cow] {
  def property1(animal: Cow): Cow = ???

  def property2(animal: Cow): Cow = ???
}

object AnimalImplRegistrar {
  def getRegisteredAnimals: Map[String, BasePropertyImpl[Animal]] = Map(
    "Dog" -> DogPropertyImpl,
    "Cow" -> CowPropertyImpl,
  )
}

object Main {
  def main(args: Array[String]): Unit = {
    val animal = AnimalImplRegistrar.getRegisteredAnimals.get("Dog").get
    aminal.property1(Dog())
  }
}

Вот что я пытаюсь достичь - это реализация, скажем, CowPropertyImpl, DogPropertyImpl или еще несколько других реализаций, я держу это в Mapи во время выполнения на основе пользовательского ввода я извлекаю реализацию из Map и вызываю метод этого класса Impl

1 Ответ

0 голосов
/ 08 июня 2018

Это хороший кандидат для Типового паттерна класса :

sealed trait Animal
case object Dog extends Animal
case object Cat extends Animal

trait AnimalProperties[A] {
  def property: A
} 

object AnimalProperties {
  implicit val dogProperties = new AnimalProperties[Dog.type] {
    override def property: Dog.type = ???
  }

  implicit val catProperties = new AnimalProperties[Cat.type] {
    override def property: Cat.type = ???
  }
}

def f[A](a: A)(implicit ev: AnimalProperties[A]) = {
  val a: A = ev.property
}

Основываясь на типе A (кошка, собака), мы получаем желаемые свойства каждого животного.

...