【问题标题】:Ruby Singleton avoid using instance memberRuby Singleton 避免使用实例成员
【发布时间】:2012-09-06 11:58:48
【问题描述】:

我喜欢 Ruby 的单例,但我想更好地使用它,所以这里是示例

require 'singleton'

class Foo
  include Singleton

  def initialize
    # code to setup singleton here 
  end

  def self.get_bar
    Foo.instance.get_bar
  end

  def get_bar
  end

  def get_nar
  end
end

用法

Foo.instance.get_bar(默认)或Foo.get_bar(由于我制作的静态self.get_bar方法)

有没有一种优雅的方法可以让所有方法都可以访问,而无需我为每个方法编写静态包装器?为每个方法编写似乎是多余的.instance

更新

Ruby 1.8.7

【问题讨论】:

  • 你真的需要使用 Singleton 模块吗? Foo 已经是一个单例了,你可以做 Foo.get_bar。
  • 这只是一个例子。我有配置单例,它保存哈希映射中许多文件的配置。所以我需要单例,它只会读取这些文件一次并持久化哈希映射......
  • 你也可以不使用 Singleton 模块。
  • 是的,但更喜欢这种方式,因为它的实现更简洁。
  • 怎么样?更新了问题以表明它不是 RoR 项目。

标签: ruby


【解决方案1】:

你可以混合这个模块:

module DelegateToSingleton

  def respond_to_missing?(method)
    super || instance.respond_to?(method)
  end

  def method_missing(method, *args)
    instance.send(method, *args)
  end

end

进入你的单身:

class Foo

  extend DelegateToSingleton
  include Singleton

  def foo
    'foo'
  end

  def bar
    'bar'
  end

end

这些结果:

p Foo.foo    # => "foo"
p Foo.bar    # => "bar"

DelegateToSingleton::method_missing 是它工作的原因:每当 Foo 收到一个它不知道的方法时,它只是将它转发给它的实例。

DelegateToSingleton::respond_to_missing? 不是绝对必要的,但在与 method_missing 玩花样时拥有它是一种礼貌。

对于 1.9.2 之前的 Ruby:Override respond_to? instead of respond_to_missing?

【讨论】:

    【解决方案2】:

    只需将类与实例分开即可:

    class Foo
      def initialize 
      end
    
      def get_bar
      end
    
      def get_nar
      end
    end
    
    MyFoo = Foo.new
    MyFoo.get_bar
    

    【讨论】:

    • 不是单例,而是实例。
    • 学究气。它以更好的方式为您提供您想要的界面和行为(更好的意思是更可测试、更灵活、更明显)。
    • 就像之前说的这个例子只是为了简化我的问题。真正的问题需要用单例解决,因为创建实例的成本很高。传递此实例的引用将只是创建意大利面条代码。
    • 只有一个实例(存储在MyFoo 的实例),与直接引用它相比,委托给它会产生更多开销,就像这样。此外,这是一个单例,因为它为您提供了对单个实例的全局访问点。它唯一的不同之处在于它不会限制您创建新的。我认为您将 GoF 的实现与其定义混淆了。坦率地说,我认为所提到的差异仅存在,因为他们从 Java 的 POV 中定义了它,而您无法执行上述操作(这也解释了他们的实现)
    • @Dolphin,动态分配是您的程序出现问题的征兆:某些文件在需要时被多次加载。 1.9 修复该问题的原因是它在检查文件是否已被需要之前对路径进行了规范化; 1.8.7 没有。更改您的要求,使它们都使用与路径相同的文字,或使用 File.expand_path 来规范化路径,您将不再获得动态分配。一旦您解决了多次加载所需文件的问题,无论如何您都应该这样做,那么这是更好的解决方案。
    猜你喜欢
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多