2016-11-15 2 views
0

Ich habe ein paar Objekte mit einer Funktion in jedem .Clean genannt erstellt:Scala ein Objekt aus einem variablen Namen zu nennen

HiveCleanerTbl 
HiveCleanerDb 

Diese Objekte müssen auf einem Datensatz auf einem API-Aufruf auf Basis dynamisch basierend aufgerufen werden wird gemacht, dass mein Job wissen lassen, welches Objekt zum Beispiel nennen ich habe es jetzt hart codiert:

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

im Code Früher stattdessen die möglichen Objekte hartzucodieren ist es eine Möglichkeit, dynamisch, das Objekt haben bevölkert wie :

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

Und ich habe Code, der wie folgt aussieht:

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

Wie werde ich die Clean machen als das Objekt definiert Ich möchte, dass verwenden kann seine .Clean Funktion aufrufen?

+0

Was wäre, wenn Sie ein anderes Objekt erstellen würden, das alle anderen Objekte kennt und die Funktion enthält, von der ich denke, dass sie systemName übernehmen und den zu verwendenden Reiniger bestimmen würde? Ohne mehr über Ihr Design zu wissen, weiß ich nicht, ob Sie alle anderen Objekte in einem einkapseln könnten, aber das könnte eine Möglichkeit sein. Du könntest vielleicht auch die anderen Objekte loswerden und diese Funktion haben, die im systemName eine Funktion zum 'clean' zurückgibt? Wiederum schwer zu sagen ohne mehr Wissen – Barry

Antwort

1

Ja, Sie können das tun.

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

Können sagen, Ihre hiveTbl und hiveDb reinigbar sind und können sagen, clean Verfahren auf ihnen zur Verfügung zu berufen.

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

Wenn db nicht über clean Methode dann die Art der db überprüfen und passende versuchen Muster der realen Art des db Objekt zu lösen.

Hier ist ein allgemeines Beispiel, wie Sie dies erreichen können.

Cleanable ergibt clean Methode zu A und B. Liste enthält alle Cleanables, so dass ich fortfahren kann, clean für jedes Objekt aufzurufen, ohne das Objekt zu casten.

Basierend auf bestimmten Bedingungen können Sie einige Objekte ignorieren.

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

Alle Ihre Objekte scheinen „Reiniger“ zu sein - so erstellen Sie ein Merkmal CanClean genannt, die die Methode clean(rawRecord: SomeType) und eine Eigenschaft val schema: Int definiert. Die schema wird in jedem Objekt mit dem entsprechenden Wert aufgefüllt. Dann setzen Sie alle diese Reiniger in eine Map[Int, CanClean] mit Schlüssel: schema und Wert: Objekt: CanClean. Dann können Sie cleanerMap(schema).clean(rawRecord) tun. Wenn Sie die cleanerMap nicht von Hand auffüllen möchten, können Sie mit reflection eine Liste aller Objekte erstellen, die CanClean implementieren.

Verwandte Themen