我希望使用自定义行为(方法)将Nokohiri::XML::Node
对象扩展为我自己的唯一对象。
我有以下对象:
class RDFNode < Nokogiri::XML::Node
def get_tag
self.at_xpath("Path/to/tag")
end
end
和Node Factory:
class RDFNodeFactory
@doc = Nokogiri::XML.parse('rdf_file.xml')
def self.get_node(id)
@doc.xpath_at("Path/to/rdf/node[@id=#{id}]")
end
end
我的问题是Ruby中的最佳Ruby实践和基本OOP。
如何让RDFNodeFactory.get_node("someid")
返回RDFNode
而不是Nokogiri::XML::Node
?我以前在Java中使用类型转换,但我们在Ruby中没有。
我应该修改Nokogiri::XML::Node
类而不是将其扩展到自定义类吗?什么是更可接受的做法?
答案 0 :(得分:3)
您应该移动get_tag方法并使用Open Classes.的概念将其添加到已存在的Nokogiri::XML::Node
,而不是仅仅为了添加一个方法来扩展Nokogiri::XML::Node
类,这看起来像:
class Nokogiri::XML::Node
def get_tag
self.at_xpath("Path/to/tag")
end
end
这在Ruby标准方面完全没问题,只是确保在将此方法添加到Nokogiri :: XML :: Node时没有任何副作用,例如get_tag已经存在。
关于公开课(假设没有当前的冲突)与继承第三方图书馆的对比:
这是一种有效的恐惧,这就是为什么在使用开放类和更新第三方库时必须非常小心。但是,如果你想到它,如果一个库改变了它们的代码,它会弄乱你的代码......当你使用开放类或从代码继承时,这将发生。当这一切都归结为时,你就会有依赖性,无论如何都必须小心。
答案 1 :(得分:1)
实例方法绑定到对象,而不是类,因此无法将对象“转换”为另一个类。但是在ruby中,您可以向现有类添加方法:
class Nokogiri::XML::Node
def get_tag
self.at_xpath("Path/to/tag")
end
end
甚至可以将方法添加到单个对象:
def @doc.get_tag
self.at_xpath("Path/to/tag")
end
答案 2 :(得分:0)
我所拥有的(某种)解决方案是遏制
class RDFNode
attr_reader :node
def initialize(node)
@node = node
end
def get_tag(id)
node.at_xpath("Path/to/tag")
end
end
现在我保留了模块化但却失去了继承的所有功能!不完美,但这是一个开始。也许有一些改进方法(用Nokogiri :: XML :: Node扩展RDFNode并为Nokogiri方法创建self = node)?