2012-11-09 10 views
10

Ich habe über Singletons in Ruby gelesen. Ich hatte nie wirklich die Notwendigkeit, sie vorher zu benutzen, aber ich wurde neugierig und beschloss, sie zu suchen, um zu sehen, ob ich sie in der Vergangenheit hätte verwenden sollen, oder vielleicht könnte ich sie in Zukunft verwenden, wenn ich wüsste was Sie sind für verwendet.Wann sollten Singleton-Klassen in Ruby verwendet werden?

Die einzigen Male, die ich denken kann, dies zu nutzen ist:

  • ? Wenn ich ein spezielles Objekt haben muss. Beispiel: "smart" Hash Objekt, das wie ein normaler Ruby-Hash mit ein paar zusätzlichen Macken wirkt.
  • Wenn ich es so machen möchte, kann nur eine Instanz einer Klasse existieren.

Allerdings bin ich mir nicht wirklich sicher, ob ich die Notwendigkeit für eines der oben genannten hatte.

+0

Sprechen Sie über die Singleton-Klasse, die jedes Objekt hat, oder sprechen Sie über die Singleton-Bibliothek, mit der Sie eine Klasse als pseudo-global deklarieren können, mit nur einer einzigen Instanz überhaupt? – Phrogz

+0

@Phrogz über "Singleton-Bibliothek, mit der Sie eine Klasse zu einem pseudo-globalen mit nur einer Instanz überhaupt möglich erklären?" aber ich hatte keine Ahnung, dass es eine Bibliothek ist? Ich dachte, es ist eine eingebaute Ruby-Funktion. – omninonsense

+1

Ich beziehe mich auf [dieses Modul] (http://ruby-doc.org/stdlib-1.9.3/libdoc/singleton/rdoc/Singleton.html), das Teil der Standardbibliothek ist, gegenüber der [singleton_class '] (http://ruby-doc.org/core-1.9.3/Object.html#method-i-singleton_class) und zugehörige [Methoden] (http://ruby-doc.org/core-1.9.3 /Object.html#method-i-singleton_methods) (das Teil des Ruby-Kerns ist). – Phrogz

Antwort

10

Beachten Sie, dass eine Klassenvermischung im Singleton-Modul funktional einer Klasse oder einem Modul mit "Klassen" -Methoden und entweder einem garantierten Initialisierungsaufruf oder einer Inline-Initialisierung entspricht. Vergleichen Sie diese Verwendung von Singleton:

require 'singleton' 
class Bar 
    include Singleton 
    attr_reader :jam 
    def initialize 
    @jam = 42 
    end 
    def double 
    @jam *= 2 
    end 
end 

b1 = Bar.instance 
b1.double 
b2 = Bar.instance 
b2.double 
p b1.jam   #=> 168 

mit dieser nicht-magic-Modul:

module Foo 
    @jam = 42 
    def self.double 
    @jam *= 2 
    end 
    def self.jam 
    @jam 
    end 
end 

Foo.double 
Foo.double 
p Foo.jam   #=> 168 

In beiden Fällen können Sie ein einziges globales Objekt, das Zustand hält. (Weil jede Konstante, die Sie im globalen Gültigkeitsbereich erstellen, einschließlich Klassen und Modulen, ein globales Objekt ist.)

Der einzige funktionale Unterschied besteht darin, dass Sie mit der Singleton die Initialisierung des Objekts verzögern, bis Sie das erste Mal danach gefragt haben .

Wenn Sie also Klassenmethoden für eine Klasse oder ein Modul haben und diese verwenden, um den Status dieses Objekts zu ändern (z. B. eine Klasse, die alle Unterklassen protokolliert), verwenden Sie im Wesentlichen ein Singleton .

4

Wie Sie sagten, wird eine Singleton-Klasse benötigt, wenn Sie nur eine Instanz der Klasse benötigen. Ein sehr gutes Beispiel für die Singleton-Klasse in einem allgemein akzeptierten Rahmen ist die Rails Logger-Klasse.

5

In Ruby werden immer Singleton-Klassen verwendet. Tatsächlich hat jedes Objekt eine Singleton-Klasse. (Hinweis: Singleton-Klassen werden aus Performancegründen nur beim ersten Zugriff erstellt, aber das ist eine Leistungsoptimierung. Semantisch wird jedesmal, wenn Sie versuchen, eine Singleton-Klasse zu betrachten, diese vorhanden sein.)

So genannt "Klassenmethoden" zum Beispiel existieren in Ruby nicht. Sie sind nur normale Instanzmethoden der Singleton-Klasse des Klassenobjekts. (Es ist so viel einfacher, stattdessen "Klassenmethode" zu sagen.)

Jedes Mal, wenn Sie eine Methode mit der def foo.bar-Syntax definieren, fügen Sie der Singleton-Klasse foo eine Methode hinzu.

+0

Ich bin mir dessen bewusst, aber ich kann mir einfach keine Zeit vorstellen, in der ich jemals eine Methode für ein einzelnes Objekt definieren müsste, abgesehen von der Zuordnung zu einer Klasse, die wahrscheinlich ein spezifisches Beispiel ist – omninonsense

+3

Manchmal gibt es Dinge, die eigentlich nur reine "Funktionen" sind, die keinem Objekt angehören und keinen Zustand haben. Aber Sie möchten sie immer noch in einen Namensraum setzen. Zum Beispiel das 'Math'-Modul. –

+0

Ah, ich habe das tatsächlich benutzt, jetzt, wo ich daran denke. Nun, ich fühle mich jetzt albern. : sadface: – omninonsense

1

Ihr zweiter Aufzählungspunkt ist genau auf Punkt. Stellen Sie sich eine Singleton-Klasse als ein völlig statisches Objekt vor. Die Booleschen und Null-Objekte in Ruby sind Beispiele.

+1

Tatsächlich sind 'true',' false' und 'nil' alle reguläre Instanzen von regulären Klassen (' TrueClass', 'FalseClass' und' NilClass'). Sie könnten mit Singleton-Klassen definiert worden sein (und das könnte sogar ein besseres Design sein), aber aus irgendeinem Grund sind sie nicht. –

Verwandte Themen