我目前正在阅读Gregory Brown Ruby Best Practices一书。在早期,他正在讨论从相关类的辅助方法重构某些功能,到模块上的某些方法,然后使用模块extend self
。
之前没有看到过,在快速谷歌之后,发现模块上的extend self
允许模块上定义的方法相互看见,这是有道理的。
现在,我的问题是你什么时候会做这样的事情
module StyleParser
extend self
def process(text)
...
end
def style_tag?(text)
...
end
end
然后在
的测试中引用它@parser = Prawn::Document::Text::StyleParser
而不是像这样的东西?
class StyleParser
def self.process(text)
...
end
def self.style_tag?(text)
...
end
end
是否可以将它用作mixin?还是有其他原因我没看到?
答案 0 :(得分:38)
类应该用于需要实例化或需要跟踪状态的功能。模块既可以用作将功能混合到多个类中的方式,也可以用作提供不需要实例化或跟踪状态的一次性功能的方法。类方法也可以用于后者。
考虑到这一点,我认为区别在于你是否真的需要一堂课。当您拥有需要某些单例功能的现有类时,类方法似乎更合适。如果您所做的只包含单例方法,那么将它作为模块实现并通过模块直接访问它会更有意义。
答案 1 :(得分:7)
在这种特殊情况下,我可能既不会使用类也不会使用模块。
一个类是对象的工厂(注意复数)。如果您不想创建该类的多个实例,则不需要它存在。
模块是方法的容器,在多个对象之间共享。如果不将模块混合到多个对象中,则不需要它存在。
在这种情况下,看起来你只想要一个对象。所以使用一个:
def (StyleParser = Object.new).process(text)
...
end
def StyleParser.style_tag?(text)
...
end
或者:
class << (StyleParser = Object.new)
def process(text)
...
end
def style_tag?(text)
...
end
end
但正如@Azeem已经写道:为了做出正确的决定,你需要更多的背景。我不太熟悉Prawn的内部人员,知道为什么Gregory做出了这个特别的决定。
答案 2 :(得分:-1)
如果您想要实例化,请使用类。你的问题的其余部分需要更多的背景才有意义。