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