Scala 最佳实践 : Trait Inheritance vs Enumeration

标签 scala object singleton enumeration

我目前正在尝试 Scala 并寻找最佳实践。我发现自己有两种相反的方法来解决一个问题。我想知道哪个更好,为什么,哪个更传统,以及您是否知道其他一些更好的方法。第二个对我来说看起来更漂亮。

<强>1。基于枚举的解决方案

import org.squeryl.internals.DatabaseAdapter
import org.squeryl.adapters.{H2Adapter, MySQLAdapter, PostgreSqlAdapter}
import java.sql.Driver

object DBType extends Enumeration {
  val MySql, PostgreSql, H2 = Value

  def fromUrl(url: String) = {
    url match {
      case u if u.startsWith("jdbc:mysql:") => Some(MySql)
      case u if u.startsWith("jdbc:postgresql:") => Some(PostgreSql)
      case u if u.startsWith("jdbc:h2:") => Some(H2)
      case _ => None
    }
  }
}

case class DBType(typ: DBType) {
  lazy val driver: Driver = {
    val name = typ match {
      case DBType.MySql => "com.mysql.jdbc.Driver"
      case DBType.PostgreSql => "org.postgresql.Driver"
      case DBType.H2 => "org.h2.Driver"
    }
    Class.forName(name).newInstance().asInstanceOf[Driver]
  }
  lazy val adapter: DatabaseAdapter = {
    typ match {
      case DBType.MySql => new MySQLAdapter
      case DBType.PostgreSql => new PostgreSqlAdapter
      case DBType.H2 => new H2Adapter
    }
  }
}

<强>2。基于单例的解决方案

import org.squeryl.internals.DatabaseAdapter
import org.squeryl.adapters.{H2Adapter, MySQLAdapter, PostgreSqlAdapter}
import java.sql.Driver

trait DBType {
  def driver: Driver
  def adapter: DatabaseAdapter
}

object DBType {
  object MySql extends DBType {
    lazy val driver = Class.forName("com.mysql.jdbc.Driver").newInstance().asInstanceOf[Driver]
    lazy val adapter = new MySQLAdapter
  }

  object PostgreSql extends DBType {
    lazy val driver = Class.forName("org.postgresql.Driver").newInstance().asInstanceOf[Driver]
    lazy val adapter = new PostgreSqlAdapter
  }

  object H2 extends DBType {
    lazy val driver = Class.forName("org.h2.Driver").newInstance().asInstanceOf[Driver]
    lazy val adapter = new H2Adapter
  }

  def fromUrl(url: String) = {
    url match {
      case u if u.startsWith("jdbc:mysql:") => Some(MySql)
      case u if u.startsWith("jdbc:postgresql:") => Some(PostgreSql)
      case u if u.startsWith("jdbc:h2:") => Some(H2)
      case _ => None
    }
  }
}

最佳答案

如果您声明一个密封特征DBType,您可以通过详尽检查对其进行模式匹配(即,如果您忘记了一种情况,Scala 会告诉您)。

无论如何,我不喜欢 Scala 的枚举,而且我并不是唯一一个这样做的人。我从不使用它,如果有什么东西枚举确实是最简洁的解决方案,那么最好使用 Java 的枚举来用 Java 编写它。

关于Scala 最佳实践 : Trait Inheritance vs Enumeration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7700507/

相关文章:

scala - 如何发布带有校验和(MD5、SHA1)的工件?

scala - 如果 csv 列标题包含空格,则在 Spark 中将 csv 转换为 parquet 会出错

c# - 如何读取数组列表中对象的属性

arrays - jq:递归合并对象并连接数组

scala - 特征之间的差异?

scala - 当您重写方法时,Scala 类中的指令顺序如何工作

javascript - 在 JavaScript 中声明一个没有名字的函数

php - PHP 中的单例引用和递归

php - 在 php 中制作 mysql 单例数据库类的任何更简单/更好的方法?

objective-c - 对每个对象而不对每个类使用dispatch_once_t