動的言語で訪問者パターンを実装する好ましい方法は何ですか?
-
09-06-2019 - |
質問
自分自身の練習として、サンプルプログラムをさまざまな言語に翻訳していました。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 ステートメント。
所属していません StackOverflow