2008-09-04 13 views
3

Als Übung für mich selbst übersetzte ich ein Beispielprogramm in verschiedene Sprachen. Beginnend in C#, ich hatte eine Besucher-Muster-Schnittstelle wie folgt:bevorzugte Methode, um Besuchermuster in dynamischen Sprachen zu implementieren?

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

Umzug in Ruby (oder Python, oder was auch immer), erhalte ich nicht mehr Versand vom Compiler basierend auf Art. Soll ich den Versand im Besucher selbst vornehmen?

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 

    ... 

Oder sollte ich tun, um die Versendung in den verschiedenen specializaions des Zimmers:

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

Oder gibt es eine andere bevorzugte Idiom, das in dynamischen Sprachen verwendet wird?

Antwort

3

Meine Empfehlung ist es, den früheren Ansatz zu verwenden. Für jeden Ansatz gibt es Vor- und Nachteile. Ersteres ist schwieriger zu pflegen, da die Anzahl der Zimmertypen zunimmt; Letzteres ist schwieriger, da die Anzahl der Cleaner-Typen zunimmt.

In Ruby, könnten Sie

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

PS versuchen: nicht alle dynamisch typisierten Sprachen nicht in der Lage sind Versand zu tun, basierend auf Typ; Einige können den Typ ableiten oder, falls dies nicht möglich ist, kann erzwungenes Casting verwenden, um die richtige Methode unter den überladenen Optionen auszuwählen.

3

Ich würde mit der zweiten Version gehen. Der erste Code sieht aus wie der Code-Geruch, den der Besucher lösen soll: lange if-else-if- oder Switch-Case-Anweisungen.