我在这里遇到设计问题。我有以下结构。
trait Table
object Table1 extends Table
object Table2 extends Table
// and so on till Table200
我有命令行界面,用户指定需要执行的表名。所以我遇到的问题是根据用户指定的表名(String类型)实例化类。我正在寻找一种不使用反射的解决方案。
答案 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传递该值的输入。