如果单身人士如此糟糕,为什么Scala会为他们提供语言支持?

时间:2012-08-01 08:54:58

标签: scala object static singleton anti-patterns

  

可能重复:
  Why are singleton objects more object orientated?

为什么Scala对Singleton反模式有语言支持?如果Scala从Java继承了static关键字,那么object关键字的合法用例会被遗漏吗?

4 个答案:

答案 0 :(得分:10)

至少有一个前面的区别,因为Scala中的object实际上是一个对象(即一个实例),而不是在Java中,它只是在类本身上调用的方法

这意味着它避免了关于单例的一个主要抱怨 - 因为一个实例,它可以被传递并连接到方法中,因此可以在测试期间换出其他实现等等。如果它是单体的推荐替代方法的语法糖 - 使用getInstance()方法的类返回默认的单个实例。

也就是说,我认为Singleton反模式更多地是关于 design 而不是语言功能。如果你构建你的代码库,以便在大多数类中隐含地连接某些单片依赖,那么无论语言特性如何,你都会遇到改变它的问题。

Scala中存在objects的合法用例(例如,messages to Actors使用case objects,或者其中有几个将sealed trait扩展为alternative to enums )。语言功能可以被滥用,但在我看来,它比Java的static更不容易被滥用,而且更有用。

答案 1 :(得分:6)

没有国家的单身人士并不那么糟糕。我将对象(在scala中)视为将函数(行为)放入的模块。

答案 2 :(得分:3)

如果你使用一个物体来保持状态,那就是单身人士遇到灾难的情况,因为可能没有办法清除它,而这是单身人士反模式的主要例子之一。一个没有可变状态且具有纯函数的对象在这方面更不容易引起疼痛,这是一个例子:

object StringSerializer extends Serializer[String] {
  // Implementation goes here.
}

在这种情况下,不需要新建一个Serializer实例,这样可以使代码更简单,性能也更好。

答案 3 :(得分:2)

例如类型类。静态类和单例之间的区别在于,单例是对象,可以作为参数传递。例如,此代码无法使用静态类构建:

trait TypeClass[A] {
  def method(x: A): A
}

implicit object IntTypeClass extends TypeClass[Int] {
  def method(x: Int) = x*x
}

def foo[A](x: A)(implicit tc: TypeClass[A]) = tc.method(x)

scala> foo(2)
res0: Int = 4