4

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 モジュールに直接移動するだけですが、アクセサーが拡張オブジェクトに存在することが実際に理にかなっている、より複雑なシナリオではどうでしょうか? これは単に懸念の不適切な分離の問題ですか?

ミックスインは、拡張オブジェクトの状態を知る必要のないカプセル化された動作を追加するのに便利です。実際、私の直感では、ミックスインはどのような状態についても認識すべきではないと教えてくれます。状態の知識が必要な場合は、通常、次の 2 つの選択肢のいずれかにフォールバックします。

  • 状態をクラスに入れ、継承階層ではなく、構成を介して追加します。これに関する私の問題は、そこにいるルビストが状態にアクセスするミックスインを作成していることを知っていることです。これにより、(私にとって)直感的ではないにしても、読みやすくなります。

  • マウスピースをパラメーターとしてモジュールに渡します。これだとデザインがごちゃごちゃしているような気もするし、ルビーの世界観としては忌まわしいとさえ感じます。

このコードは他の人を悩ませますか? Ruby を使っている賢い人がたくさんいることは知っているので、問題は私にあると思います。私は何が欠けていますか?私はただリラックスする必要がありますか?あなたならどうしますか?

4

2 に答える 2

1

それはモンキーパッチの場合と同じだと思います: それを行っても問題ありませんが、最初に代替手段がないことを確認する必要があります (つまり、インターフェイスを使用してクラスを変更することはできません)。それについて明示的に (ドキュメント、コメント、およびインターフェイスで、このメソッドが必要であり、呼び出されることが言及されていることを確認してください)、そうでない場合は有用なエラー メッセージをスローします。

于 2011-02-14T07:55:22.207 に答える
0

Ruby のアクセサーはインターフェースであり、実装ではありません。

たとえば、 を呼び出しperson.height_in_feet=た場合、高さが実際にインスタンス変数として実装されている単位はわかりません。それは、メートル、フィート、またはキュビットである可能性があります。

アクセサーを使用したミックスインの実例の 1 つがEnumerableモジュールです。私が作成するどのクラスにもこのモジュールを含めていませんが、その機能には満足しています。mapとのような便利なメソッドを提供しますがeach_with_index、DRY のままです。「mixee」のすべてのメソッドでアクセスするオブジェクトの実装は 1 つだけでありmap、 を使用するすべてのオブジェクトに対して、何をするかの定義は 1 つだけEnumerableです。

于 2011-02-09T03:48:58.957 に答える