0

I have a few objects created with a function called .clean in each one:

HiveCleanerTbl
HiveCleanerDb

These Objects need to be called dynamically based on a record based on an API call being made that will let my Job know what object to call for instance I have it hard coded right now:

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

Earlier in the code instead of hardcoding the possible Objects is there a way to dynamically have the object populated like:

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

And I have code that looks like this:

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

How will I make the cleanObject defined as the object I want to use that can call its .clean function?

1
  • What if you made another object that had knowledge of all the other objects and contained the function that I think would take systemName and determine which cleaner to use? Without knowing more about your design I don't know if you could encapsulate all the other objects in one but that might be a possibility. You could also perhaps get rid of the other objects and have this function that takes in the systemName return a function to 'clean'? Again , hard to say without more knowledge Commented Nov 15, 2016 at 19:10

2 Answers 2

1

Yes, you can do that.

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

Lets say your hiveTbl and hiveDb are cleanable and lets say clean method is available on them to invoke.

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

If db does not have clean method then check the type of db and try pattern matching to resolve the real type of the db object.

Here is a general example how you can achieve this.

Cleanable gives clean method to A and B. List contains all cleanables so I can go ahead calling clean on each object without type casting the object.

Based on certain condition you can ignore clean some objects.

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 
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

All your objects seem to be "cleaners" - so create a trait called CanClean that defines the method clean(rawRecord: SomeType) and a property val schema: Int. The schema will be populated in each object with the appropriate value. Then put all these cleaners in a Map[Int, CanClean] with key: schema and value: object: CanClean. Then you can do cleanerMap(schema).clean(rawRecord). If you do not want to populate the cleanerMap by hand, you can use reflection to make a list of "all objects that implement CanClean".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.