什么是混入和或性状的一些很好的例子?
-
21-08-2019 - |
题
我读了关于Ruby,并了解其混入模式,但想不出很多有用的功能,混入(因为我不习惯有这样的想法最有可能)。所以我想知道什么是有用的密新功能很好的例子?
由于
编辑:背景的位。我是从C ++和其他对象的语言来,但我在这里的疑问是,Ruby的说,它不是继承的混入,但我一直看到混入作为多重继承,所以我怕我试图过早地将其归类到自己的安乐窝,并没有真正神交一个mixin是什么。
解决方案
井通常的例子中,我认为是持久性
module Persistence
def load sFileName
puts "load code to read #{sFileName} contents into my_data"
end
def save sFileName
puts "Uber code to persist #{@my_data} to #{sFileName}"
end
end
class BrandNewClass
include Persistence
attr :my_data
def data=(someData)
@my_data = someData
end
end
b = BrandNewClass.new
b.data = "My pwd"
b.save "MyFile.secret"
b.load "MyFile.secret"
试想模块由一个Ruby忍者,它仍然存在类的状态到文件写入。结果
现在假设我写了一个全新的课,我可以通过说include ModuleILike
混合,再利用持久性的功能。你甚至可以在运行时模块。我得到负荷和刚刚在混合保存免费的方法,这些方法都一样,你自己写的类的人。代码/行为/功能复用不继承!
那么,你正在做的是包括方法的方法表类(不是字面上正确的,但接近)。
其他提示
它们通常用于添加某种形式的标准功能的一类,而不必重新定义这一切。你也许可以把它们有点像Java接口,但不要只定义了需要实现的方法列表,其中许多人会真正的是的通过,包括模块来实现。
有几个例子在标准库:
单件 - 可以混合到任何类的模块,使之成为单例。初始化方法是由私人,和一个实例方法加入,这确保只有永远一个类的实例在应用程序中。
可比 - 如果包含在该模块中的一类,定义<=>方法,其中所述当前实例与另一个对象进行比较,并表示它是更大的,也足以提供<,<=,==,> =, >之间,并且?方法
可枚举 - 从该模块中混合,并且限定的每个方式,将得到支持的所有其他相关方法例如收集,注入,选择和拒绝。如果它也得到了<=>方法,那么它也将支持排序,最小值和最大值。
的DataMapper也是什么可以用简单的进行包括声明,把标准的类,以及添加到其保存到数据存储能力的有趣的例子。
在红宝石,即混入不是多重继承的原因在于,组合混入方法是一次性的东西。这不会是一个大问题,只是Ruby的模块和类是开放的修改。这意味着,如果混入一个模块类,然后添加一个方法到模块,该方法的不会的提供给你的类;其中,如果你没有它以相反的顺序,它会。
这就像订购冰淇淋锥体。如果你的巧克力洒太妃糖位作为你的混入,并与您的圆锥体,你有什么样的蛋卷冰淇淋,如果有人增加了五彩洒到巧克力洒斌回到了冰淇淋店不会改变走开。你的类,蛋筒,当混入模块,洒的bin是不会被修改。旁边的人使用该混入模块将看到的变化。
当你include
在红宝石的模块,它是模块,其中该模块的方法副本添加到包入一个时间上的要求Module#append_features
。
多重继承,按照我的理解,更像是代表团。如果你的类不知道如何做,它会询问其父母。在一个开放的环境一流,一类的父母可能已经在类创建后修改。
这就像一个RL父子关系。你的母亲可能已经学会了如何兼顾你出生后,但如果有人问你忙里忙外,你问她要么:告诉你如何(当你需要它复制)或为你做它(纯代表团),那么她马上就能在这一点上,即使你被创造之前她忙里忙外的能力了。
这是可能的,你可以修改红宝石模块“包含”修改Module#append_features
保持includers的列表更像多重继承,然后使用method_added
回调对其进行更新,但是这将是从标准的一大转变红宝石,并可能与其他代码时会导致重大问题。你可能会更好地创建名为Module#inherit
和处理代表团以及一个include
方法。
作为一个真实的例子,Enumerable
真棒。如果你定义#each
,并在您的类Enumerable
,那么,您可以访问迭代器的一大堆,而您不必每一个代码。
它在很大程度上用作一个可能使用在C ++多重继承或实现接口用Java / C#。我不知道在你的经验所在,但如果你以前做过的那些事,混入你会怎么做他们的Ruby。它的注入功能集成到类的系统化方法。