Frage

Als Übung für mich selbst übersetzte ich ein Beispielprogramm in verschiedene Sprachen.Beginnend mit C# hatte ich eine Besuchermusterschnittstelle wie folgt:

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

Wenn ich zu Ruby (oder Python oder was auch immer) wechsle, erhalte ich vom Compiler keinen Versand mehr basierend auf dem Typ.Soll ich den Versand im Besucher selbst durchführen?

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 soll ich den Versand in den verschiedenen Spezialisierungen des Raumes durchführen:

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

Oder gibt es eine andere bevorzugte Redewendung, die in dynamischen Sprachen verwendet wird?

War es hilfreich?

Lösung

Meine Empfehlung ist, den ersteren Ansatz zu verwenden.Für jeden Ansatz gibt es Vor- und Nachteile.Ersteres ist schwieriger zu pflegen, da die Anzahl der Zimmertypen zunimmt;Letzteres wird schwieriger, je mehr Reinigertypen es gibt.

In Ruby könnten Sie es versuchen

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

PS:Nicht alle dynamisch typisierten Sprachen sind nicht in der Lage, den Versand basierend auf dem Typ durchzuführen.Einige können auf den Typ schließen oder, falls dies nicht gelingt, eine erzwungene Umwandlung verwenden, um die richtige Methode aus den überladenen Optionen auszuwählen.

Andere Tipps

Ich würde mich für die zweite Version entscheiden.Der erste sieht aus wie die Art von Code-Geruch, den Visitor lösen soll:lange if-else-if- oder case-switch-Anweisungen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top