前几天,我在#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
然而,索蒙说,在这里使用全球国家被认为是不好的做法。
我理解为什么全局状态对依赖多个后端的东西不利,因为全局状态的全局部分停止如此全局,并且本地化到那个后端。或者它会干扰依赖注入。
但是,我真的想不出为什么这是坏事的任何其他原因。而且,如果并发性成为一个问题(需要多个后端),那么我们可以更新代码以使用Redis(或类似的东西)。另外,我找到this question on programmers.sxc,但它无法理解为什么上面的代码被认为是如此糟糕?还有什么可以替代?
答案 0 :(得分:2)
由于您没有提及的几个原因,全球州很糟糕:
您提到的全局状态的特定形式@@
变量,对于Ruby特定原因也是不好的:
@@
变量在类及其所有子类之间共享。所以即使你认为它是封装的,它也不是。如果有人将您的User
类子类化,并声明变量@@list
来存储不相关的数据,那么这尤其糟糕。 Ruby不会抱怨,并且整个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