Scala 我应该避免定义';对象';在斯卡拉?
我认为Scala中的“对象”与Java中的Singleton非常相似,这被认为不是一个好的设计实践。对我来说,Singleton就像定义全局变量的另一种方式,这很糟糕。我编写了一些类似这样的Scala代码,因为它很简单,而且可以工作,但代码看起来很难看:Scala 我应该避免定义';对象';在斯卡拉?,scala,design-patterns,Scala,Design Patterns,我认为Scala中的“对象”与Java中的Singleton非常相似,这被认为不是一个好的设计实践。对我来说,Singleton就像定义全局变量的另一种方式,这很糟糕。我编写了一些类似这样的Scala代码,因为它很简单,而且可以工作,但代码看起来很难看: object HttpServer { // I'm the only HttpServer instance in this program. var someGlobalState: State def run() { //
object HttpServer { // I'm the only HttpServer instance in this program.
var someGlobalState: State
def run() {
// do something
}
}
我尽量避免这样做。什么时候定义Scala对象比较好?全局变量本身并不坏。你只需要知道什么时候合适。因此,
对象
本身并不坏。例如:
object HelloWorld {
def main(args:Array[String]){
println("Hello World")
}
}
在不深入讨论这个话题的情况下,我喜欢这样想:“我想要这些东西中的‘只有一个’是因为它最能反映现实吗?还是这是一条让事情‘正常运转’的懒惰捷径?”
不要盲目而广泛地应用“单身是坏的”规则。在很多情况下,“只有一件”是有意义的。在您的特定情况下,我需要更多的上下文来给出更具体的建议。否。许多Scala库严重依赖对象 Singleton模式的主要目标是只存在一个对象实例。对象也是如此 您可能会将其误用为全局变量,但这不是重点
例如,对象是工厂方法的好地方,或者是保存函数的模块的替代品。为什么假设只需要全局变量?全局值和方法非常有用。这是您将在Scala中使用的
object
的大部分内容
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...
}
现在,您必须小心使用全局变量,如果您愿意,您可以在对象中实现它们。然后,您需要弄清楚自己是否粗心大意(注意:将同一个类的实例传递给程序中的每个类和方法同样有问题),或者您正在执行的操作的逻辑是否最好地由单个全局值反映出来
这里有一个非常非常糟糕的主意:
object UserCache {
var newPasswordField: String = "foo bar"
}
两个用户同时更改他们的密码,然后…嗯…你会有一些不开心的用户
另一方面,
object UserIDProvider {
private[this] var maxID = 1
def getNewID() = this.synchronized {
var id = maxID
maxID += 1
id
}
}
如果你不这样做,同样,你会有一些不高兴的用户。(当然,您确实需要在启动时读取磁盘上有关用户ID号的一些状态……或者将所有这些信息保存在数据库中……但您明白了这一点。)var someGlobalState的可能重复项解决了您的问题。Scala对象并不意味着全局状态或任何状态。经验法则:
object
s不应该有任何可变状态。(有时可能会被破坏,但这些情况应该以怀疑的态度处理。)是的,你必须小心测试。在很多领域,全球性的事情会让你陷入麻烦。对于一个相对初学者来说,即使没有单例测试,创建一个测试噩梦(可以说)也是相当容易的。我认为在您的示例中使用像UserIDProvider这样的对象不是一个好方法。它向任何人公开此对象。您可以在代码中的任何位置操作此对象中维护的全局状态。有时我很懒,不想太费劲地考虑谁需要访问这个对象,我只将它们定义为单例。我可以在以后的任何时候访问它们,而无需更改任何内容。但我认为将对象范围限制在尽可能小的范围是一种好的做法。@woodings-这取决于应用程序的范围。如果它真的关心新的用户ID——也许它是一个新的帐户服务器——那么全局就可以了。如果它只是某个巨大系统的一小部分,那么不,你可能不希望它随处可见。然而,解决这个问题的正确方法是——如果这真的是一个单一的全局问题——对单个对象使用访问限制。如果您试图通过仅实例化一个对象来模拟它,则可能会犯错误并创建两个对象。这样,编译器会为您处理它。所以,private[无论什么]对象
it。