将类方法委托给ruby中的对象

时间:2011-02-14 22:24:48

标签: ruby design-patterns jruby

我正在尝试将调用包装到类中的单例中(因为我不希望其余代码知道它们正在与单例进行通信),并且我查看了委托模块。

在我的代码中,我有类似的东西:

class HideSingleton
  @@obj = SingletonClass.instance # x is an instance of SingletonClass
  # I want to be able to say HideSingleton.blah,
  # where 'blah' is instance method of SingletonClass instance (i.e., 'x')
  SimpleDelegator.new @@obj.field
end

class SingletonClass < BaseClass
  attr_reader :field
  def initialize
    @field = SimpleDelegator.new super(BaseClass Constructor params)
  end
end

然后在irb:

> require 'singleton_class'
> x = SingletonClass.new
> x.blah  # 'blah' is a method that is present in BaseClass instance
> require 'hide_singleton'
> y = HideSingleton

我该怎样做y.blah

2 个答案:

答案 0 :(得分:1)

我认为您尝试执行的操作更简单,但要完成委托给单例类的隐藏单例类,您可以执行以下操作:

require 'delegate'
require 'forwardable'

class BaseClass
  def blah
    puts 'hi'
  end
end

class SingletonClass < BaseClass
  attr_reader :field
  def initialize
    @field = SimpleDelegator.new(BaseClass.new)
  end
end

class HideSingleton
  def self.obj
    @@obj ||= SingletonClass.new.field
  end

  def self.method_missing *args
    obj.send *args
  end
end

然后您可以进行以下调用:

x = SingletonClass.new
x.blah
hi
=> nil
HideSingleton.blah
hi
=> nil

答案 1 :(得分:0)

有一些问题需要注意:

HideSingleton类本身仍然有几个方法(来自Object和Module),这些方法将在HideSingleton上调用,而不是在SingletonClass上调用。例如,如果我们在类中有不同的常量:

class SingletonClass < BaseClass
  SingletonConst = :foo
end

class HideSingleton
  HideConst = :bar
end

然后在两个类上调用类方法常量会导致:

SingletonClass.constants
  #=> [:SingletonConst]

HideSingleton.constants
  #=> [:HideConst]

任何标准方法(const_get,class_eval,dup,respond_to?等)都是如此。为避免这种情况,您需要卸载要传递给SingletonClass的HideSingleton中的方法(或显式转发它们)。