什么时候在Ruby中使用Singleton类是明智的?

omn*_*nse 11 ruby singleton

我正在阅读Ruby中的Singletons.我以前从来没有真正需要使用它们,但我很好奇并决定查看它们,看看我是否应该在过去使用它们,或者如果我知道它们是什么我将来也可以使用它们用于.

我能想到的唯一一次使用它是:

  • 当我需要一个特殊的对象.示例:"智能" Hash对象,其行为类似于普通的Ruby哈希,并带有一些额外的怪癖.
  • 当我想要它时,只有一个类的实例可以存在.

但是,我不确定我是否需要上述任何一种.

Phr*_*ogz 10

请注意,在Singleton模块中混合的类在功能上等同于具有"类"方法的类或模块,以及保证的初始化调用或内联初始化.比较Singleton的这种用法:

require 'singleton'
class Bar
  include Singleton
  attr_reader :jam
  def initialize
    @jam = 42
  end
  def double
    @jam *= 2
  end
end

b1 = Bar.instance
b1.double
b2 = Bar.instance
b2.double
p b1.jam          #=> 168
Run Code Online (Sandbox Code Playgroud)

有了这个无魔法模块:

module Foo
  @jam = 42
  def self.double
    @jam *= 2
  end
  def self.jam
    @jam
  end
end

Foo.double
Foo.double
p Foo.jam          #=> 168
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,您都有一个维护状态的全局对象.(因为您在全局范围内创建的每个常量(包括类和模块)都是全局对象.)

唯一的功能区别在于,Singleton您可以延迟对象的初始化,直到您第一次请求它为止.

因此,如果您在类或模块上有"类"方法,并且使用它们来更改该对象的状态(例如,一个类跟踪从中继承的所有子类),那么您实际上使用的是单例.


iGb*_*nam 5

就像你说的那样,当你需要只有一个类的实例时,需要一个Singleton类.在广泛接受的框架中,Singleton类的一个很好的例子是Rails Logger类.


Jör*_*tag 5

你总是在Ruby中使用单例类.实际上,每个对象都有一个单例类.(注意:出于性能原因,单例类实际上只在您第一次访问它们时创建,但这是性能优化.从语义上讲,每次尝试查看单例类时,它都会存在.)

例如,所谓的"类方法"实际上并不存在于Ruby中.它们只是类对象的singleton类的常规实例方法.(相反,说"课堂方法"要容易得多.)

每次使用def foo.bar语法定义方法时,都要向singleton类添加方法foo.

  • 有时,有些东西实际上只是纯粹的"功能",不属于某个对象,也没有任何状态.但是你仍然希望将它们放在命名空间中.例如,`Math`模块. (3认同)