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中使用。