Factory-Methoden in Ruby
Was ist die raffiniertesten, die meisten Ruby-wie die Möglichkeit zu haben, einen einzigen Konstruktor return ein Objekt des entsprechenden Typs?
Um genauer zu sein, hier ein dummy-Beispiel: angenommen ich habe zwei Klassen Bike
und Car
die Unterklasse Vehicle
. Ich möchte diese:
Vehicle.new('mountain bike') # returns Bike.new('mountain bike')
Vehicle.new('ferrari') # returns Car.new('ferrari')
Habe ich vorgeschlagen, eine Lösung unten, aber es nutzt allocate
scheint Weg zu Umsetzung schwer. Was sind einige andere Ansätze, oder ist mir das eigentlich ok?
InformationsquelleAutor der Frage Peter | 2009-10-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn ich eine factory-Methode, die nicht genannt1
new
oderinitialize
ich denke mal, dass nicht wirklich eine Antwort auf die Frage "wie mache ich eine ... - Konstruktor ...", aber ich denke, das ist, wie ich es tun würde...1 ist. Aufruf der Methode Fabrik funktioniert wirklich gut in diesem Lehr-Beispiel, aber IRL möchten Sie vielleicht zu prüfen, @AlexChaffee's Ratschläge in den Kommentaren.
InformationsquelleAutor der Antwort DigitalRoss
Ich Tat dies heute. Übersetzt in die Fahrzeuge würde es so Aussehen:
Gefällt mir, dass die Bezeichnungen für die Klassen gehalten werden, mit den Klassen selbst, anstatt die Informationen über einen Unterklasse gespeichert, die mit der Oberklasse. Der Konstruktor wird nicht aufgerufen
new
aber ich sehe keinen Vorteil bei der Verwendung, insbesondere name, und es würde die Dinge schwieriger.Beachten Sie, dass etwas muss sich vergewissern, dass diese Unterklassen werden geladen, bevor vehicle_from_name ausgeführt wird (vermutlich diese drei Klassen werden in unterschiedlichen source-Dateien), da sonst der Oberklasse haben keine Möglichkeit zu wissen, welche Unterklassen vorhanden ist, d.h. Sie kann nicht davon abhängen, autoload zu ziehen, diese Kategorien bei der Ausführung des Konstruktors.
Ich dies Problem gelöst, indem alle Unterklassen, z.B. ein
vehicles
Unterverzeichnis und fügen Sie diese am Ende dervehicle.rb
:Verwendet die
require_all
gem (gefunden bei https://rubygems.org/gems/require_all und https://github.com/jarmo/require_all)InformationsquelleAutor der Antwort clacke
Angepasst hierich habe
InformationsquelleAutor der Antwort Peter
Was ist ein Modul enthalten, statt der einer Oberklasse? So erhalten Sie immer noch
#kind_of?
zu arbeiten, und es gibt keine Standard -new
ihm in die Quere.InformationsquelleAutor der Antwort James A. Rosen
und das können wir jetzt tun...
Können Sie sehen, dieses Beispiel in dem Buch Design Patterns in Ruby (Amazon link).
InformationsquelleAutor der Antwort rrichards
Können Sie reinigen die Dinge ein wenig durch die änderung
Vehicle#new
:In der letzten Zeile
Vehicle.new
mit der ternären Aussage ist wichtig. Ohne die Prüfung fürklass == self
wir stecken in einer Endlosschleife und generieren die StackError dass die anderen darauf hin, früher. Beachten Sie, dass wir haben, zu nennensuper
mit Klammern. Sonst würden wir uns am Ende den Aufruf mit Argumenten, diesuper
nicht erwarten.Und hier sind die Ergebnisse:
InformationsquelleAutor der Antwort Peter Wagenet