首页 > 解决方案 > Factory with companion object where each type of object takes a common parameter

问题描述

I have a class like this -

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

I have a companion object that returns different types of caches. It has functions that require a base table name and can construct the cache.

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);
  }
}

The object does a few more things and the Cache class has more parameters, which makes it useful to have a companion object to create different types of Caches. The baseTableName parameter is same for all of the caches. Is there a way in which I can pass this parameter only once and then just call the functions to get different types of caches ?

Alternative to this is to create a factory class and pass the baseTableName parameter to constructor and then call the functions. But I am wondering if it could be done in any way with the Companion object.

标签: scalafactorycompanion-object

解决方案


最简单的方法是将您的工厂放在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我将您的 Cache 也更改为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

推荐阅读