为什么Scala对Singleton反模式有语言支持?如果Scala从Java继承了static
关键字,那么object
关键字的合法用例会被遗漏吗?
答案 0 :(得分:10)
至少有一个前面的区别,因为Scala中的object
实际上是一个对象(即一个实例),而不是在Java中,它只是在类本身上调用的方法
这意味着它避免了关于单例的一个主要抱怨 - 因为是一个实例,它可以被传递并连接到方法中,因此可以在测试期间换出其他实现等等。如果它是单体的推荐替代方法的语法糖 - 使用getInstance()
方法的类返回默认的单个实例。
也就是说,我认为Singleton反模式更多地是关于 design 而不是语言功能。如果你构建你的代码库,以便在大多数类中隐含地连接某些单片依赖,那么无论语言特性如何,你都会遇到改变它的问题。
Scala中存在objects
的合法用例(例如,messages to Actors使用case objects
,或者其中有几个将sealed trait
扩展为alternative to enums )。语言功能可以被滥用,但在我看来,它比Java的static
更不容易被滥用,而且更有用。
答案 1 :(得分:6)
答案 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