我已经读过,模块提供的主要服务是包含和分组几个对象所需的类似函数。但即使你确定只有一个对象需要它的服务,为一个类似解析器的东西创建一个模块是一个好习惯吗?
答案 0 :(得分:3)
模块有两个目的。您已经注意到的第一个是允许将功能添加到不同的类集(在继承树之外的多种含义)。第二个更常见的用途是组织名称空间。当您看到ActiveRecord::Base
或BSON::ObjectID
等代码时,这些宝石的作者已将其功能分别放在模块ActiveRecord
和BSON
中,这样可防止其类名与之冲突他们所包含的应用程序或其他库。
使用你提到的解析器,听起来像你想要构建一个单例类而不是一个模块。
答案 1 :(得分:2)
即使您在一个地方使用模块,它也可以帮助组织创建模块。例如,您可能有许多方法都是相关的,但与包含模块的代码并不真正相关。这类似于类提供的组织,除了模块不关注于对象
答案 2 :(得分:1)
模块提供的主要服务是 包含和分组相似的功能 几个对象需要的东西
我会把它重新命名为“将可能至少需要 一个对象的类似功能组合在一起”。很常见的是,您不知道有多少类最终会包含或扩展模块(例如,如果您正在编写库)
除此之外,我还看到了两个“主要目的”:
included
的回调。这可能看起来微不足道,但回调是许多有趣的元编程技术的关键。 答案 3 :(得分:0)
我会去上课(如果你没有太多的代码)。将它放在/ lib
下class Parse
def self.xml(xml_string)
...
end
end
Parse.xml("<xml></xml>")
模块确实是一组类似的功能。如果你有很多解析代码,你可以这样做:
class Xml
acts_as_parser
end
class Json
acts_as_parser
end
...
acts_as_parser将从模块中加载一组函数。
答案 4 :(得分:0)
但即使您确定只有一个对象需要其服务,为类似解析器创建模块是一个好习惯吗?
在Ruby中,模块通过分离关注点帮助了很多,并且非常适合进行“面向方面”的编程(即,使用mixin的乐趣)。
# Basic Hierarchy
class X
def say ; 'X' end
end
class Y < X
def say ; super + 'Y' end
end
y = Y.new
y.say #=> 'XY'
# Throwing in an aspects/mixins
module A
def say ; super + 'A' end
end
class Y
include A
end
y.say #=> 'XAY'
# Throwing in another aspects/mixins
module B
def say ; super + 'B' end
end
class Y
include B
end
y.say #=> 'XABY'
答案 5 :(得分:0)
当面对一个过大的类时,有时我会根据它的功能将它分成几个模块,并且只有这些模块才有一个空的类。