2016-11-15 44 views
0

我有一个在每一个所谓的清洁机壳函数创建几个对象:斯卡拉调用从变量名对象

HiveCleanerTbl 
HiveCleanerDb 

这些对象需要基于基于API调用记录动态调用正在取得会让我的工作知道叫什么对象比如我有硬编码现在:

def matchSchema(schema:Int): Any = schema match { 
      case 1 => HiveCleanerTbl.clean(rawRecord) 
      case 32 => HiveCleanerDb.clean(rawRecord) 
... 

的代码,而不是硬编码的可能的对象早些时候,有没有办法来动态有填充像对象:

val systems = List[(String, String, Int)] = List((hiveTbl,HiveTblCleaner,6), (hiveDb,HiveDbCleaner,7)) 

而且我的代码看起来像这样:

systems.foreach(x => if(x._1 == systemName) { 
       cleanObject = x._2 
      }) 

我怎么会让定义我想用,可以调用它的清洁机壳函数对象的cleanObject?

+0

如果你让另一个知道所有其他对象的对象包含了我认为需要systemName并确定使用哪个清理器的函数?不知道更多关于你的设计,我不知道你是否可以将所有其他对象封装在一个中,但这可能是一种可能性。你也可以摆脱其他对象,并让这个函数在systemName中返回一个函数'clean'?再次,没有更多的知识很难说 – Barry

回答

1

是的,你可以做到这一点。

val systems = List[(Cleanable, String, Int)] = List((hiveTbl,HiveTblCleaner,6), (hiveDb,HiveDbCleaner,7)) 

比方说你hiveTblhiveDb是清洁的,并让说clean方法可以用它们来调用。

systems.foreach { 
    case (db: Cleanable, "cleanSchemeName", _) => 
    db.clean 
    case _ =>() //ignore 
} 

如果db没有clean方法然后检查的数据库类型,并尝试模式匹配,以解决实际类型db对象。

这是一个通用的例子,你可以实现这一点。

Cleanable给出clean方法为AB。 List包含所有可清理对象,因此我可以继续在每个对象上调用clean而不用类型转换对象。

基于某些条件,您可以忽略清洁一些对象。

trait Cleanable { 
    def clean(): Unit 
} 

case class A(a: Int) extends Cleanable { 
    override def clean(): Unit = println("cleaned A") 
} 

case class B(a: Int) extends Cleanable { 
    override def clean(): Unit = println("cleaned B") 
} 

val cleanableStuff: List[(String, Cleanable)] = List(("clean", A(10)), ("donot_clean", B(10))) 

def cleanAll(list: List[(String, Cleanable)]): Unit = { 
    list.foreach { 
    case ("donot_clean", v) => //Ignore 1st object 
    case (_, v) => v.clean() //clean other objects 
    } 
} 
1

您的所有对象似乎是“清洁工” - 所以创建一个名为CanClean定义方法clean(rawRecord: SomeType)和属性val schema: Int特质。 schema将在每个对象中填充适当的值。然后将所有这些清洁剂置于Map[Int, CanClean]中,其中键为:schema,值为:对象:CanClean。然后你可以做cleanerMap(schema).clean(rawRecord)。如果您不想手动填充cleanerMap,则可以使用反射来列出“实现CanClean的所有对象”。