[英]When do we use ruby module vs using class composition?
之前已经提出过与此类似的问题,但我特别要求使用组合作为使用模块mixins的替代方法。
class Helper
def do_somthing
end
end
如果我需要“使用”一个类而不是继承它,我只需编写并使用它。
class MyStuff
def initialize
helper = Helper.new
helper.do_something
end
end
为什么我要为此创建一个模块:
module Helper
def do_something
end
end
class MyStuff
include Helper
end
我看到的唯一区别是,如果我使用模块,那么就不会有很多Helper
对象。 但是我没有看到任何东西,周围有更多物体,而不是更大的物体。
而且,我不知道将来是否需要将其子类化。 那么我该如何判断我的库的用户是想要使用模块mixin,还是想要使用合成?
当Helper
和MyStuff
类之间的关系是所有权之间的关系时,请使用组合 。 这被称为“has-a”关系。 例如,假设你有Person
类和Car
类。 你会使用作文,因为一个人有车:
class Person
def initialize
@car = Car.new
end
end
class Car
def accelerate
# implementation
end
end
当Helper
“充当” MyStuff
,请使用模块mixin 。 在这种情况下, Helper
扮演 MyStuff
的角色 。 这与“is-a”关系略有不同,这意味着您应该使用传统继承 。 例如,假设我们有一个Person
类和一个Sleeper
模块。 一个人有时扮演一个睡眠者的角色,但其他物体也是如此 - Dog
, Frog
甚至Computer
实例。 其他每一类都代表着可以入睡的东西。
module Sleeper
def go_to_sleep
# implementation
end
end
class Person
include Sleeper
end
class Computer
include Sleeper
end
这是“ 鸭子打字 ”的问题。 如果您希望您的班级表现得像Helper
,那么您可以include
。 无论您是要封装 Helper
行为,都require
正确的选择。
混合Enumerable
,通过仅实现each
方法,为您的类提供大量方法。 包装Array
您可以隐藏其他人的迭代并使用它来保存您的数据。 反之亦然。
模块mixin更像是多重继承,因此遵循通常的继承与组合规则 - 是-a或has-a。 顺便说一下,它include Helper
, require 'Helper'
。
我可以分享一些东西:
如果您需要在不同的类和模块中共享常见行为,您应该将其转换为模块,以便以后可以将模块include
在您喜欢的任何位置。 它也将有助于测试,因为它已经干了。
在责任的情况下,您可以将其转换为新模块,以便清楚地理解并提高代码库的可读性。 这将有助于减少主要类的大小,这应该易于遵循和维护。
您可能会注意到的一件事include
为您的instance
添加功能,其中extend
对Class
本身。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.