最近看元编程 (第二版),第 126 页:“单件类也有自己的单件类”,实际编程中的用途是啥?求赐教。
请看 单件模式
摘录:Singleton 就是确保一个类只有唯一的一个实例。Singleton 主要用于对象的创建,这意味着,如果某个类采用了 Singleton 模式,则在这个类被创建后,它将有且仅有一个实例可供访问。很多时候我们都会需要 Singleton 模式,最常见的比如我们希望整个应用程序中只有一个连接数据库的 Connection 实例;又比如要求一个应用程序中只存在某个用户数据结构的唯一实例。我们都可以通过应用 Singleton 模式达到目的。
也不能说没有实际用途吧,以下面代码为例。
class Person
class << self
class << self
def private_attributes(*params)
# some code
end
end
# 这样就可以在这里直接使用 private_attributes了啊
private_attributes :some_config
end
end
不过再深一层好像就真的有点过分了,singleton class 的 singleton class 的 singleton class。。。
额外的说,你在 singleton 里定义的 class method 其实都是定义在 singleton class 的 singleton class 里的,例如:
class Person
class << self
def self.private_attributes(*params)
# some code
end
# 这样就可以在这里直接使用 private_attributes了啊
private_attributes :some_config
end
end
或者在 singleton 里 extend 一个 module
class Person
class << self
extend SomeModule
end
end
#13 楼 @taojay315 或者在 singleton 里 include 一个 module
class Person
class << self
include SomeModule
end
end
#14 楼 @pathbox 不是啊,题主问的是 singleton 的 singleton,所以如果是 include 应该是这样:
class Person
class << self
class << self
include SomeModule
end
end
end
其实很简单啊,你想那么复杂干嘛,就是跟 singleton class 的功能都一致,为 object 提供实例方法。
你可以看看我最近写的这个
http://blog.jerry-tao.com/ruby/2016/01/14/singleton_class_for_dummy.html
module Some
def hi
p 'hi hi'
end
end
class Person
class << self
class << self
include Some
end
p self.hi # "hi hi" "hi hi" 输出了两遍
end
end
class Person
class << self
extend Some
end
p self.hi # NoMethodError: undefined method `hi' for Pe:Class
p self.new.hi # NoMethodError: undefined method `hi' for #<Pe:0x007fe40bf6cb00>
p hi # NameError: undefined local variable or method `hi' for Pe:Class
end
请问 extend 的情况怎么使用呢?这几种调用的都报错
我理解就是给实例对象插入方法,对 engine_class 来说实例对象就是这个类;对具体的对象来说,obj.method 也是其中一种 engine method.
在我的实际应用中,每个用户都有一个虚拟货币仓库,为了方便对账,我又建立了一个属于系统的虚拟货币仓库,所有用户的货币发放都通过系统仓库发放,最后整个系统应该是平账。这就要求系统里边有且只有一个系统仓库,这个时候单件类模式就非常有用了。
class CoinWarehouse < ActiveRecord::Base
belongs_to :user
# ...
end
class UserCoinWarehouse < CoinWarehouse
end
class SystemCoinWarehouse < CoinWarehouse
def self.singleton
@singleton ||= (first || create)
end
end