2013-04-02 132 views
8

之前已经提出过类似这样的问题,但是我特别提出了使用组合作为使用模块mixin的替代方法。什么时候使用ruby模块vs使用类组合?

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,或者想要使用组合?

+1

'require'不是你在这里需要的。你需要'include'。 – Linuxios

+0

thnx。修正 – codeObserver

+0

当然。乐意效劳。 – Linuxios

回答

14

HelperMyStuff类之间的关系是所有权之一时,请使用组成。这被称为“has-a”的关系。例如,假设您有Person类和Car类。你会使用成分,因为一个人有一辆车:

class Person 
    def initialize 
    @car = Car.new 
    end 
end 

class Car 
    def accelerate 
    # implementation 
    end 
end 

Helper“行为像”MyStuff,使用模块混入。在这种情况下,的角色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 

桑迪梅斯的实用Object-Oriented Design in Ruby是这些主题的优秀资源。

0

模块mixin更像是多重继承,所以请遵循通常的继承vs组合规则 - is-a或has-a。顺便说一句,它是include Helper,而不是require 'Helper'

0

有几件事我可以分享:

  • 如果您需要共享在不同的类和模块共同行为,你应该让成模块,这样以后你可以include模块哪里你喜欢。它也将帮助测试,因为它已经干了。

  • 在责任的情况下,您可以将它变成新的模块,以使其明确理解并提高代码库的可读性。这将有助于减少应易于遵循和维护的主要类的大小。

有一件事你可能会注意到include增加功能,以您的instance哪里extend确实给Class本身。

1

这是“Duck Typing”的问题。如果你想让你的课程像Helper一样行事,你可以做include。无论您是要encapsulateHelper的行为,正确的选择是require

混合Enumerable在,你给你的类通过实施唯一的each方法的巨大负荷的方法。包装Array您可以隐藏其他人的迭代并仅将其用于保存数据。反之亦然。

+0

你能解释一下吗? *'通过实现唯一的每个方法'* –

+1

您的课程是实现**只有一个**('each')方法并混合使用'Enumerable'以产生......嗯......迭代的所有乐趣。 – mudasobwa

+0

我的不好!没有得到你 –

相关问题