3

自分の練習問題として、サンプルプログラムをさまざまな言語に翻訳していました。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

または、動的言語で使用される別の好ましいイディオムはありますか?

4

2 に答える 2

3

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

Rubyでは、試すことができます

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

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

于 2008-09-04T19:31:52.880 に答える
3

私は2番目のバージョンに行きます。最初のものは、Visitor が解決するはずの一種のコードのにおいのように見えます: 長い if-else-if または switch-case ステートメント。

于 2008-09-04T20:03:27.860 に答える