2008-09-04 6 views
3

私自身の練習として、サンプルプログラムをさまざまな言語に翻訳していました。 C#で始まる、私はそうのようなビジターパターンインタフェースなかっ:ルビーに移り訪問者パターンを動的言語で実装するのに好ましい方法は?

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

(や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 

    ... 

それとも私が部屋の異なるspecializaionsでの発送を行う必要があります。

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

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

答えて

3

前者の方法を使用することをお勧めします。それぞれのアプローチにプラスとマイナスがあります。前者は部屋タイプの数が増えるにつれて維持することが難しい。後者はクリーナータイプの数が増えるにつれてより困難になります。

Rubyでは、あなたは

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

PSを試みることができる:すべての動的型付け言語は型に基づいてディスパッチを行うことができないではありません。いくつかは型を推論することも、失敗することもあり、強制的なキャストを使ってオーバーロードされたオプションの中から適切なメソッドを選ぶことができます。

3

私は2番目のバージョンに行きます。最初のものはVisitorが解決しようとしているコードのようなものです:長いif-else-ifまたはswitch-case文。

関連する問題