前几天我在 #ruby-lang 频道上与某人谈论了@@class_variables. 这一切都始于用户询问跟踪连接到其服务器的用户的最佳方式是什么(我稍微简化了它,但这就是要点)。
所以,我建议:
class User
@@list = {} #assuming he wants to look up users by some type of ID
def initialize(user_id, ...)
@@list[user_id] = self
#...
end
end
Run Code Online (Sandbox Code Playgroud)
然而,有人说在这里使用全局状态被认为是不好的做法。
我理解为什么全局状态对于依赖多个后端的东西来说是不好的,因为全局状态的全局部分不再那么全局,而是变得本地化到那个后端。或者它会干扰依赖注入。
不过,我真的想不出任何其他原因说明这很糟糕。而且,如果并发性成为问题(需要多个后端),那么我们可以更新代码以使用 Redis(或类似的东西)。
另外,我在programmers.sxc上发现了这个问题,但这并不能帮助我理解为什么上面的代码被认为如此糟糕?另外,还有什么选择呢?
由于您没有提到的几个原因,全局状态很糟糕:
您提到的全局状态的特定形式(@@变量)对于 Ruby 特定的原因也是不好的:
@@Ruby 中的变量在类及其所有子类之间共享。因此,即使您认为它是封装的,但事实并非如此。如果有人对您的类进行子类化,并声明一个用于存储不相关数据的User变量,这尤其糟糕。@@listRuby 不会抱怨,整个 User 类树的状态都会受到损害。类封装:如果您需要全局状态,请让一个类使用 setter 和 getter 来维护它。这使得第 2 点和第 3 点以及@@探针无效,因为它使用了类@变量。例子:
class User
class << self
@list = {}
def add_user(uid, user)
#Do validation here
@list[uid] = user
end
#More methods like add_user
end
def initialize(user_id, ...)
User.add_user(user_id, self)
end
end
Run Code Online (Sandbox Code Playgroud)