rubyists是否会参考mixins的访问者?

时间:2011-02-08 19:40:38

标签: ruby mixins

从mixin方法中引用扩展对象上的访问器是否被认为是不好的做法?一个简单的例子:

module WindInstrument
  def play
    mouthpiece.blow  #requires a mouthpiece
  end
end

class Saxophone
  attr_reader :mouthpiece

  def initialize
    @mouthpiece = Mouthpiece.new
  end

  include WindInstrument
end

Saxophone.new.play

在这种情况下,我实际上只是将喉舌的需求直接移到WindInstrument模块,但是在更复杂的场景中,访问者是否真的有理由生活在扩展对象上呢?这只是一个不恰当的问题分离问题吗?

Mixins对于添加不需要了解扩展对象状态的封装行为非常有用。事实上,我的直觉告诉我,mixin不应该知道任何状态,无论如何。如果它需要了解状态,我通常会回到以下两种选择之一:

  • 将状态放在一个类中,然后通过合成而不是通过继承层次结构添加它。我的问题是我知道 ruby​​ists了有创建mixins访问状态,这使得更具可读性,如果不太直观(对我而言)设计。

  • 将咬嘴作为参数传递给模块。即使我可以看出这似乎使设计变得混乱,感觉就像红宝石世界观中的憎恶。

    < / LI>

这段代码是否打扰了其他人?我知道有很多聪明的人在那里使用红宝石,所以我认为问题是我的。我错过了什么?我只是需要放松一下吗? 做什么?

2 个答案:

答案 0 :(得分:1)

我认为它与猴子修补相同:可以这样做,但你必须确保首先没有替代品(即你不能使用你的界面修改类),其次,你必须非常明确(确保文档,注释和界面提到我们的方法是必需的并将被调用)并抛出一个有用的错误消息,如果它不是

答案 1 :(得分:0)

Ruby的访问器是接口,而不是实现。

例如,如果您调用person.height_in_feet=,则您不知道实际高度实际实现的单位为实例变量。它可能是米,英尺或肘。

使用访问者的mixins的一个真实示例是Enumerable模块。虽然我没有在我创建的任何类中包含此模块,但我对它的功能感到满意。它为您提供了方便的方法,如mapeach_with_index,同时保持DRY - 只有一个实现您可以使用“mixee”的所有方法访问的对象,并且只有一个定义对于使用map的任何对象,Enumerable的作用。