我应该避免在Scala中定义"对象"吗?

woo*_*ngs 3 design-patterns scala

我认为Scala中的"对象"非常类似于Java中的Singleton,这被认为不是一个好的设计实践.单身对我来说就像定义全局变量的另一种方式是BAD.我写了一些这样的Scala代码,因为它很简单并且可以工作,但代码看起来很难看:

object HttpServer { // I'm the only HttpServer instance in this program.
  var someGlobalState: State
  def run() {
    // do something
  }
}
Run Code Online (Sandbox Code Playgroud)

我试图避免这样做.什么时候定义Scala对象好?

And*_*ann 10

不是.许多Scala-Libraries严重依赖于对象.

Singleton-Pattern的主要目标是只存在一个Object实例.对象也是如此.

您可能会将其误用为全局变量,但这不是重点.

例如,对象是工厂方法的好地方,或者替换模块来保存函数.


Rex*_*err 8

为什么你认为你只需要全局变量?全球价值观和方法非常有用.这是您object在Scala中使用的大部分内容.

object NumericConstant {
  val Pi = 3.1415926535897932385   // I probably will not change....
}

object NumericFunctions {
  def squared(x: Double) = x*x     // This is probably always what we mean...
}
Run Code Online (Sandbox Code Playgroud)

现在,你必须使用全局变量要小心,如果你愿意,你可以在对象中实现它们.然后你需要弄清楚你是否粗心(注意:将一个类的同一个实例传递给程序中的每个类和方法同样有问题),或者你所做的事情的逻辑是否最好由一个单一的全球价值.

这是一个非常非常糟糕的主意:

object UserCache {
  var newPasswordField: String = "foo bar"
}
Run Code Online (Sandbox Code Playgroud)

两个用户同时更改密码......好吧......你会有一些不满意的用户.

另一方面,

object UserIDProvider {
  private[this] var maxID = 1
  def getNewID() = this.synchronized {
    var id = maxID
    maxID += 1
    id
  }
}
Run Code Online (Sandbox Code Playgroud)

如果你不再做这样的事情,那么你将会有一些不满意的用户.(当然,你真的需要在启动时读取磁盘上有关用户ID号的某些状态...或者将所有内容保存在数据库中......但是你明白了.)