Ruby模块可以被描述为单例类吗?
我试图从设计模式的角度来理解Ruby模块的目的。
Ruby模块本质上只是一个只初始化一次的类吗?
include MyModule
ruby类是一个可以创建实例的模块。 像类一样,模块可以有方法,但是你不能创建模块的实例。 这是他们之间的唯一区别。
在实践中,模块通常用于:
- 名称空间
- 混入
- 保持function
名称空间
以下是用作名称空间的模块示例:
module MyLib class Foo end class Bar end end
这些类的全名是MyLib :: Foo和MyLib :: Bar。 因为它们包含在命名空间中(可能是唯一的),所以名称Foo和Bar不能与程序或其他库中定义的Foo或Bar冲突。
混入
这是一个用作混合的模块:
module Mixin def foo puts "foo" end end
由于您无法创建Mixin模块的实例,因此您可以通过包含(混合)模块来访问foo:
class MyClass include Mixin end MyClass.new.foo # => foo
function
像类一样,模块可以保存不在任何实例上运行的函数。 为此,您可以在模块中定义类方法:
module SomeFunctions def self.foo puts "foo" end end
模块中定义的类方法就像类中定义的类方法一样。 打电话给它:
SomeFunctions.foo # => foo
模块在Ruby中有两种用途:常量的命名空间和mixins。
常量的命名空间仅仅意味着在
FOO = 1 module Bar FOO = 2 end module Baz FOO = 3 end
在三个不同的命名空间中有三个不同的FOO
:一个在全局命名空间(实际上是Object
),一个在Bar
,一个在Baz
。
更有趣的用例是mixins:mixin基本上是一个在其超类上进行参数化的类。 或者,换句话说:mixin是一个可以在inheritance图中多次出现的类,每次都有不同的超类。
将此与多重inheritance进行对比:在多重inheritance中,类只能在inheritance图中出现一次 ,但它可能有多个超类。 mixin可能在inheritance图中出现多次 ,但每次出现只有一个超类。
特别是,当你将一个模块M
混合到一个C
类中时,Ruby中发生的是创建一个实际的类(一个所谓的include类 )(让它称之为M′
),它的方法表,常量表和变量表指针指向到M
的方法表,常量表和变量表,并且该类M′
成为C
的超类,旧的超类成为M′
的超类。
类是模块,但模块不是类。 Module
实际上是Class
的超Class
。 如果你知道OOP,那就是你需要知道的全部内容。
Ruby模块最好用作名称空间并在mixins中使用。