带有伴随对象的工厂,其中每种类型的对象都有一个公共参数

Factory with companion object where each type of object takes a common parameter

我有一个 class 这样的 -

class Cache (
  tableName: String,
  TTL: Int) {
  // Creates a cache
}

我有一个伴生对象 returns 不同类型的缓存。它具有需要基本 table 名称的功能,并且可以构造缓存。

object Cache {
   def getOpsCache(baseTableName: String): Cache = {
    new Cache(s"baseTableName_ops", OpsTTL);
  }

  def getSnapshotCache(baseTableName: String): Cache = {
    new Cache(s"baseTableName_snaps", SnapshotTTL);
  }

  def getMetadataCache(baseTableName: String): Cache = {
    new Cache(s"baseTableName_metadata", MetadataTTL);
  }
}

这个对象做了更多的事情,Cache class 有更多的参数,这使得有一个伴随对象来创建不同类型的 Cache 很有用。 baseTableName 参数对于所有缓存都是相同的。有没有一种方法可以只传递一次这个参数,然后调用函数来获取不同类型的缓存?

替代方法是创建工厂 class 并将 baseTableName 参数传递给构造函数,然后调用函数。但我想知道是否可以通过 Companion 对象以任何方式完成它。

最简单的方法是把你的工厂放在 case class:

case class CacheFactory(baseTableName: String) {

  lazy val getOpsCache: Cache = 
     Cache(s"baseTableName_ops", OpsTTL)

  lazy val getSnapshotCache =
     Cache(s"baseTableName_snaps", SnapshotTTL)

  lazy val getMetadataCache =
    Cache(s"baseTableName_metadata", MetadataTTL) 
}

我喜欢 case classes 我也将您的缓存更改为 case class:

case class Cache(tableName: String, TTL: Int)

如您所见,我调整了您的 Java 代码以更正 Scala代码.

如果你想把它放在companion object,你可以使用implicits,比如:

object Cache {

  def getOpsCache(implicit baseTableName: String): Cache = 
     Cache(s"baseTableName_ops", OpsTTL)

  def getSnapshotCache(implicit baseTableName: String) =
     Cache(s"baseTableName_snaps", SnapshotTTL)

  def getMetadataCache(implicit baseTableName: String) =
    Cache(s"baseTableName_metadata", MetadataTTL) 
}

那么你的客户看起来像:

implicit val baseTableName: String = "baseName"

cache.getSnapshotCache
cache.getMetadataCache

考虑像这样创建代数数据类型

sealed abstract class Cache(tablePostfix: String, ttl: Int) {
  val tableName = s"baseTableName_$tablePostfix"
}
case object OpsCache extends Cache("ops", 60)
case object SnapshotCache extends Cache("snaps", 120)
case object MetadataCache extends Cache("metadata", 180)

OpsCache.tableName // res0: String = baseTableName_ops