如何创建“类簇” (带有具体子类实例的工厂类)在 Ruby 中?
我想创建一个抽象类,它将根据初始化参数创建具体实例。示例:
class SomethingGeneric
def self.new(type, arg)
class_name = "#{type.capitalize}Something"
if obj.const_defined?(class_name)
a_class = obj.const_get(class_name)
else
raise ArgumentError, "Concrete something '#{type}' was not found"
end
obj = a_class.new(arg)
return obj
end
end # class
那么我想要 FooSomething < SomethingGeneric,BarSomething <一些通用的东西等等。然后当我这样做时:
obj = SomethingGeneric.new("foo", arg)
我会得到 FooSomething 实例。
我的问题是“新”方法。我已经定义了 SomethingGeneric.new,但是 FooSomething 和 BarSomething 是 SomethingGeneric 的子类,因此它们继承了“new”方法,该方法在此处使用错误的参数调用:
obj = a_class.new(arg)
解决方案之一是为工厂方法“new”使用另一个名称。不过,我想坚持方便并保留名为“new”的抽象超类工厂方法。
解决这个问题最干净、正确的方法是什么?
I would like to create an abstract class which will create concrete instances depending on initialization parameter. Example:
class SomethingGeneric
def self.new(type, arg)
class_name = "#{type.capitalize}Something"
if obj.const_defined?(class_name)
a_class = obj.const_get(class_name)
else
raise ArgumentError, "Concrete something '#{type}' was not found"
end
obj = a_class.new(arg)
return obj
end
end # class
Then I would like to have FooSomething < SomethingGeneric, BarSomething < SomethingGeneric and more. Then when I do:
obj = SomethingGeneric.new("foo", arg)
I would get FooSomething instance.
My problem here is the "new" method. I have defined SomethingGeneric.new, however FooSomething and BarSomething are subclasses of SomethingGeneric therefore they inherit the "new" method which is called with wrong arguments here:
obj = a_class.new(arg)
One of the solution would be to use another name for the factory method 'new'. However I would like to stick with convenience and keep the abstract superclass factory method named 'new'.
What is the cleanest correct way to solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的新方法应该采用一个参数:*args,
你需要从数组中获取第一个项目作为你的类型var,然后从数组中删除该项目,这样你就可以将其余的参数传递给下一个新的参数称呼。
Array#shift 将为您提供第一个项目,然后将其删除。
your new method should take one param: *args
you'll want to grab the first item out of the array as your type var, and then remove that item from the array so you can pass the rest of the args down to the next new call.
Array#shift will give you the first item and then remove it.
真正的问题是你需要这种行为的目的是什么?看起来您来自像 Java 这样的语言,其中工厂之类的东西是常态。您是否需要这种行为以便知道该对象将对您将要使用的特定方法做出响应?使用接口怎么样?
类似的事情:
如果你真的想使用抽象类,你可以这样做:
在这种情况下,行为将是这样的:
The real question is what do you need this behavior for? It appears you're coming from a language like Java where Factories and the like are the norm. Do you need this behavior so that you know that the object will respond to specific methods you are going to use? How about using an interface?
Something like:
If you really want to use an Abstract class you could do something like:
In this case the behavior would be something like this: