在ruby中将类方法委托给对象
我试图在类中封装对单例的调用(因为我不想让代码的其余部分知道它们正在与单例对话),并且我查看了委托模块 在我的代码中,我有如下内容:在ruby中将类方法委托给对象,ruby,design-patterns,jruby,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 Sing
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
我该怎么做呢?我认为有一个更简单的实现来实现您要做的事情,但是要完成委托给单例类的隐藏单例类,您可以执行以下操作:
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
有一些问题需要注意: HideSingleton类本身仍然有几个方法(来自对象和模块),这些方法将在HideSingleton而不是SingletonClass上调用。例如,如果类中有不同的常量,如下所示:
class SingletonClass < BaseClass
SingletonConst = :foo
end
class HideSingleton
HideConst = :bar
end
对于任何标准方法(const_get、class_eval、dup、respond_to?)也是如此。为了避免这种情况,您需要卸载HideSingleton中希望传递给SingletonClass(或显式转发)的方法。在您的irb示例中,您的意思是
x=SingletonClass.instance
?假设您使用的是singleton stdlib。没错,请编辑我的问题以反映这一点。那么SingletonClass
包括singleton
?或者是基类
?基类->无单例。SingletonClass->基类的子类,但包括Singleton。我听说这是推荐的方法。对不起,我想我应该把我的问题说得更清楚一点。我试图将所有内容都委托给Singleton类,所以def_委托人可能不合适?根据我给您的这些新信息,您有什么建议?我做了一个简单的修改,以便您可以使用HideSingleton类上缺少的方法_来委托给delegator对象。非常感谢。漂亮的解决方案。还有一个问题:我听说method_missing比调用常规方法慢一个数量级。。。如果我希望经常使用这段代码(比如rails中的每个HTTP请求),这会带来明显的性能差异吗?可能不会,但如果您担心性能,我建议您对此进行基准测试。如果您发现缺少的方法实际上是一个明显的差异,那么您必须显式定义要委托的方法,在这种情况下,您不能简单地说:将所有内容委托给另一个类,您必须显式地说每个方法都委托给特定的委托者。一般来说,只要您没有为委托定义特定的方法,您就在使用方法\u。
x = SingletonClass.new
x.blah
hi
=> nil
HideSingleton.blah
hi
=> nil
class SingletonClass < BaseClass
SingletonConst = :foo
end
class HideSingleton
HideConst = :bar
end
SingletonClass.constants
#=> [:SingletonConst]
HideSingleton.constants
#=> [:HideConst]