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

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

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

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

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

请注意,在Singleton模块中混合的类在function上等同于具有“类”方法的类或模块,并且保证初始化调用或内联初始化。 比较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 

有了这个无魔法模块:

 module Foo @jam = 42 def self.double @jam *= 2 end def self.jam @jam end end Foo.double Foo.double p Foo.jam #=> 168 

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

唯一的function区别在于,使用Singleton可以延迟对象的初始化,直到第一次请求它为止。

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

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

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

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

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

你的第二个要点正是关键点。 将单例类视为完全静态的对象。 ruby中的Boolean和Null对象就是例子。