繁体   English   中英

我们什么时候使用ruby模块和使用类组合?

[英]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,还是想要使用合成?

HelperMyStuff类之间的关系是所有权之间的关系时,请使用组合 这被称为“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模块。 一个人有时扮演一个睡眠者的角色,但其他物体也是如此 - DogFrog甚至Computer实例。 其他每一类都代表着可以入睡的东西。

module Sleeper
  def go_to_sleep
    # implementation
  end
end

class Person
  include Sleeper
end

class Computer
  include Sleeper
end

Sandi Metz的Ruby实用面向对象设计是这些主题的优秀资源。

这是“ 鸭子打字 ”的问题。 如果您希望您的班级表现得像Helper ,那么您可以include 无论您是要封装 Helper行为,都require正确的选择。

混合Enumerable ,通过仅实现each方法,为您的类提供大量方法。 包装Array您可以隐藏其他人的迭代并使用它来保存您的数据。 反之亦然。

模块mixin更像是多重继承,因此遵循通常的继承与组合规则 - 是-a或has-a。 顺便说一下,它include Helperrequire 'Helper'

我可以分享一些东西:

  • 如果您需要在不同的类和模块中共享常见行为,您应该将其转换为模块,以便以后可以将模块include在您喜欢的任何位置。 它也将有助于测试,因为它已经干了。

  • 在责任的情况下,您可以将其转换为新模块,以便清楚地理解并提高代码库的可读性。 这将有助于减少主要类的大小,这应该易于遵循和维护。

您可能会注意到的一件事include为您的instance添加功能,其中extendClass本身。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM