运行时设计的Scala类实例化

时间:2018-03-14 22:10:58

标签: scala

我在这里遇到设计问题。我有以下结构。

trait Table
object Table1 extends Table
object Table2 extends Table
// and so on till Table200

我有命令行界面,用户指定需要执行的表名。所以我遇到的问题是根据用户指定的表名(String类型)实例化类。我正在寻找一种不使用反射的解决方案。

3 个答案:

答案 0 :(得分:1)

您可以使用某种"注册表"如果你想避免使用反射:

import scala.collection.mutable

object MyApp {

  // Create some kind of "registry"
  private val TableByName: mutable.Map[String, Table] = mutable.Map()

  // Create a lookup method:
  def lookup(name: String): Option[Table] = TableByName.get(name)

  // Each table would register itself
  trait Table {
    TableByName.put(this.toString, this)
    override def toString: String = this.getClass.getSimpleName.replace("$", "")
  }

  // Instantiate each object after declaring it, or else it won't "register"
  object Table1 extends Table; Table1
  object Table2 extends Table; Table2
  // ...

  def main(args: Array[String]): Unit = {
    // Now we can lookup our table in the registry by name
    val result: Option[Table] = lookup("Table2")
    println(result)
  }

}

答案 1 :(得分:1)

scala> trait Table
// defined trait Table    
scala> object Table1 extends Table
// defined object Table1   
scala> object Table2 extends Table
// defined object Table2
scala> val name = "Table2"
// name: String = Table2


scala> val map = Map (1 -> Table1, 2 -> Table2)
// map: scala.collection.immutable.Map[Int,Table] = Map(1 -> Table1$@51549af8, 2 -> Table2$@394542f5)    
scala> def getTable (s: String) : Option [Table] = map.get (s.replaceAll ("^Table", "").toInt)
// getTable: (s: String)Option[Table]    
scala> getTable (name)
// res0: Option[Table] = Some(Table2$@394542f5)

使用数组类似:

val tblarr = Array[Table] (Table1, Table2)
val usertbl = tblarr(name.replaceAll ("^Table", "").toInt - 1)

或者,索引为0的虚拟表,没有错误倾向-1操作(容易忘记)。

答案 2 :(得分:0)

试试这个

trait Table
class Table1 extends Table
class Table2 extends Table

object Table   { 
  def apply (kind: String) = kind match {
    case "Table1" => new Table1() 
    case "Table2" => new Table2()
  } 
} 

Table("Table1")

我相信你可以在创建对象时读取cli传递该值的输入。