可能重复:
为什么单例对象更面向对象?
为什么 Scala 对 Singleton 反模式有语言支持?如果 Scala 继承了static
Java 的关键字,那么该关键字的合法用例会object
留下哪些?
可能重复:
为什么单例对象更面向对象?
为什么 Scala 对 Singleton 反模式有语言支持?如果 Scala 继承了static
Java 的关键字,那么该关键字的合法用例会object
留下哪些?
至少有一个预先的区别,因为object
Scala 中的 an 实际上是一个对象(即一个实例),而不是在 Java 中它只是在类本身上调用的方法。
这意味着它避免了关于单例的主要抱怨之一——因为它是一个实例,它可以被传递并连接到方法中,因此可以在测试期间换出其他实现等。如果有的话,它是语法糖推荐的单例替代方案 - 拥有一个带有getInstance()
返回默认单个实例的方法的类。
也就是说,我认为 Singleton 反模式更多的是关于设计而不是语言特性。如果你构建你的代码库,以便在大多数类中隐式连接一些单一依赖项,那么无论语言特性如何,你都会遇到更改它的问题。
objects
在 Scala 中有一些合法的用例(例如,case objects
用于向 Actors 发送消息,或者让其中的几个扩展 asealed trait
作为enums 的替代方案)。语言特性可能会被滥用,但在我看来,它不像 Java 那样容易被滥用,而且static
更有用。
没有状态的单身人士并没有那么糟糕。我将对象(在 scala 中)视为放入函数(行为)的模块。
如果你使用一个对象来保持状态,那么单例就是一场灾难,因为可能没有办法清除它,这是单例成为反模式的主要例子之一。没有可变状态和纯函数的对象在这方面不太容易引起痛苦,这里有一个例子:
object StringSerializer extends Serializer[String] {
// Implementation goes here.
}
在这种情况下,不需要新建 Serializer 的实例,这使得代码更简单,性能可能更好。
例如类型类。静态类和单例的区别在于,单例是对象,可以作为参数传递。例如,此代码无法使用静态类构建:
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