从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不应该知道任何状态,无论如何。如果它需要了解状态,我通常会回到以下两种选择之一:
将状态放在一个类中,然后通过合成而不是通过继承层次结构添加它。我的问题是我知道 rubyists了有创建mixins访问状态,这使得更具可读性,如果不太直观(对我而言)设计。
将咬嘴作为参数传递给模块。即使我可以看出这似乎使设计变得混乱,感觉就像红宝石世界观中的憎恶。
< / LI>这段代码是否打扰了其他人?我知道有很多聪明的人在那里使用红宝石,所以我认为问题是我的。我错过了什么?我只是需要放松一下吗? 你做什么?
答案 0 :(得分:1)
我认为它与猴子修补相同:可以这样做,但你必须确保首先没有替代品(即你不能使用你的界面修改类),其次,你必须非常明确(确保文档,注释和界面提到我们的方法是必需的并将被调用)并抛出一个有用的错误消息,如果它不是
答案 1 :(得分:0)
Ruby的访问器是接口,而不是实现。
例如,如果您调用person.height_in_feet=
,则您不知道实际高度实际实现的单位为实例变量。它可能是米,英尺或肘。
使用访问者的mixins的一个真实示例是Enumerable
模块。虽然我没有在我创建的任何类中包含此模块,但我对它的功能感到满意。它为您提供了方便的方法,如map
和each_with_index
,同时保持DRY - 只有一个实现您可以使用“mixee”的所有方法访问的对象,并且只有一个定义对于使用map
的任何对象,Enumerable
的作用。