2016-11-15 47 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的所有對象」。