Scala:带参数的Companion对象

时间:2016-08-27 10:18:12

标签: scala design-patterns singleton

我正在寻找一种使用companion初始化arguments对象的方法。我试过这个,它有re-instantiation的风险。

private[mypackage] class A(in:Int) {
  def method = {}
}

object A {

  var singleton: Option[A] = None

  def getInstance(): A = {
    if(singleton.isDefined)
      singleton.get
    else {
        throw InitializationException("Object not configured")
      }
  }

  def getInstance(in:Int): A = {
    singleton = Some(new A(in))
    singleton.get
  }
}

有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

纯Scala方式

Scala允许您使用object关键字创建类型的单个对象。 Scala确保系统中只有一个A实例可用。

private[myPackage] object A  {
  val configValue = Config.getInt("some_value")
  def fn: Unit = ()
}

A对象的类型

scala> object A {}
defined object A

scala> :type A
A.type

有关scala Explanation of singleton objects in Scala

中单例对象的更多信息

Guice Annotations

import com.google.inject.Singleton

@Singleton
class A (val value: Int) {
  def fn: Unit = ()
}

经典Java方式

使用synchronized关键字来保护getInstance在调用时不会创建多个对象。当然,类的构造函数必须是private

答案 1 :(得分:1)

您可以使用lazy val来延迟单例的创建,并将其基于var,应在启动顺序期间更新一次:

object A {
  // will be instantiated once, on first call
  lazy val singleton: A = create()

  private var input: Option[Int] = None

  // call this before first access to 'singleton':
  def set(i: Int): Unit = { input = Some(i) }

  private def create(): A = {
    input.map(i => new A(i))
      .getOrElse(throw new IllegalStateException("cannot access A before input is set"))
  }
}