質問

自分自身の練習として、サンプルプログラムをさまざまな言語に翻訳していました。C# から始めて、次のような訪問者パターンのインターフェイスがありました。

interface Visitor
    {
        void Accept(Bedroom x);
        void Accept(Bathroom x);
        void Accept(Kitchen x);
        void Accept(LivingRoom x);
    }

Ruby (または Python など) に移行すると、型に基づいてコンパイラーからディスパッチを取得できなくなりました。発送はお客様自身で行ったほうが良いでしょうか?

class Cleaner

  def accept(x)
    acceptBedroom(x) if Bedroom === x
    acceptBathroom(x) if Bathroom === x
    acceptKitchen(x) if Kitchen===x
    acceptLivingRoom(x) if LivingRoom===x
  end

  ...

それとも、ルームのさまざまな専門分野でディスパッチを行うべきでしょうか。

class Bathroom<Room
  def initialize(name)
    super(name)
  end
  def accept(visitor)
    visitor.acceptBathroom(self)
  end
end

それとも、動的言語で使用される別の推奨イディオムはありますか?

役に立ちましたか?

解決

私のお勧めは、前者のアプローチを使用することです。それぞれのアプローチにはプラスとマイナスがあります。前者は、ルーム タイプの数が増えるにつれて維持するのが難しくなります。後者は、クリーナーの種類の数が増えるにつれて難しくなります。

Rubyでは、次のことを試すことができます

def accept(x)
  send "accept#{x.class}".to_sym, x
end

追伸:すべての動的型付け言語が型に基づいてディスパッチできないわけではありません。型を推測できるものもありますが、それができない場合は、強制キャストを使用してオーバーロードされたオプションの中から適切なメソッドを選択することもできます。

他のヒント

私なら 2 番目のバージョンを使用します。最初のものは、訪問者が解決することになっている一種のコード臭のように見えます。長い if-else-if または switch-case ステートメント。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top