dimanche 19 avril 2020

Scala - How to avoid if/else condition for object factory

I am trying to solve the following problem. Problem

  • I have to write a copy method to copy from one file system to other. (i.e. local to hdfs, s3 to s3, and few more later).
  • This file system (local, s3, hdfs) could increase in future and so does actions (copy, move, delete)
  • some of the actions are cross FileSystem (i.e. Copy, Move) some aren't i.e. (Delete, List, Find)
  • I have a property file which contains source and destination location, along with some other fields (i.e count) which help me understand where to copy file.

I tried to solve the problem using Factory in following way, however it's still not able to solve Cross Platform action problem. And code doesn't look elegant.

Implementation

abstract class FileSystem(propFileURI: String) {
  def moveFile(): Unit
}

object FileSystem {

  private class HDFSystem(propFileURI: String) extends FileSystem(propFileURI) {
    override def moveFile(): Unit = {
      println(" HDFS  move file")
    }
  }

  private class S3System(propFileURI: String) extends FileSystem(propFileURI) {
    override def moveFile(): Unit = {
      println("S3 Move File ")
    }
  }

  def apply(propFileURI: String): Option[FileSystem] = {
    val properties: Properties = new Properties()

    val source = Source.fromFile( System.getProperty("user.dir")+"\\src\\main\\resources\\"+propFileURI).reader
    properties.load(source)
    val srcPath = properties.getProperty("srcPath")
    val destPath = properties.getProperty("destPath")

    if (destPath.contains("hdfs")){
       Some(new HDFSystem(propFileURI))
    }
    if (srcPath.contains("s3") && destPath.contains("s3")){
      Some(new S3System(propFileURI))
    }else{
       None
    }

  }

  def main(args: Array[String]): Unit = {
    val obj = FileSystem("test.properties")
    obj match {
      case Some(test) => test.moveFile()
      case None => println("None returned")
    }
  }
}

Question:

  1. moveFile method doesn't actually says about source location. and so how to implement same method for local->hdfs and local->s3

  2. How to move HDFSystem and S3System to seperate file?

  3. How to avoid if/else in apply method?

Aucun commentaire:

Enregistrer un commentaire