2010-04-19 26 views
17

Ich arbeite derzeit durch das Gregory Brown Ruby Best Practices Buch. Zu Beginn spricht er davon, einige Funktionen von Hilfsmethoden für eine verwandte Klasse auf einige Methoden im Modul umzuformen, und hatte dann das Modul extend self.Wann ein Modul zu verwenden, und wann eine Klasse

Hatte nicht gesehen, dass vorher, nach einem schnellen Google, herausgefunden, dass extend self auf einem Modul können Methoden auf dem Modul definiert sehen, was sinnvoll ist.

Nun ist meine Frage, wann würden Sie so etwas tun

module StyleParser 
    extend self 

    def process(text) 
    ... 
    end 

    def style_tag?(text) 
    ... 
    end 
end 

und dann mit

@parser = Prawn::Document::Text::StyleParser 

, um es in Tests beziehen sich wie diese etwas dagegen?

class StyleParser 

    def self.process(text) 
    ... 
    end 

    def self.style_tag?(text) 
    ... 
    end 
end 

ist es so, dass Sie es als Mixin verwenden können? oder gibt es andere Gründe, die ich nicht sehe?

Antwort

30

Eine Klasse sollte für Funktionen verwendet werden, für die eine Instanziierung erforderlich ist oder die den Zustand überwachen müssen. Ein Modul kann entweder als eine Möglichkeit verwendet werden, Funktionalität in mehrere Klassen zu mischen, oder als eine Möglichkeit, einmalige Merkmale bereitzustellen, die nicht instanziiert werden müssen oder um den Status zu verfolgen. Für Letzteres könnte auch eine Klassenmethode verwendet werden.

In diesem Sinne denke ich, der Unterschied liegt darin, ob Sie wirklich eine Klasse brauchen oder nicht. Eine Klassenmethode scheint besser geeignet zu sein, wenn Sie eine vorhandene Klasse haben, die eine Singleton-Funktionalität benötigt. Wenn das, was Sie machen, nur aus Singleton-Methoden besteht, ist es sinnvoller, es als Modul zu implementieren und direkt über das Modul darauf zuzugreifen.

+1

Genau das, was ich gesucht habe :-) –

-2

Wenn Sie etwas instanziieren möchten, verwenden Sie eine Klasse. Der Rest Ihrer Frage benötigt mehr Kontext, um einen Sinn zu ergeben.

3

In diesem speziellen Fall würde ich wahrscheinlich weder eine Klasse noch ein Modul benutzen.

Eine Klasse ist eine Fabrik für Objekte (beachten Sie die Mehrzahl). Wenn Sie mehrere Instanzen der Klasse nicht erstellen möchten, müssen sie nicht vorhanden sein.

Ein Modul ist ein Container für Methoden, die von mehreren Objekten gemeinsam genutzt werden. Wenn Sie das Modul nicht in mehrere Objekte mischen, besteht keine Notwendigkeit, dass es existiert.

In diesem Fall sieht es so aus, als ob Sie nur ein Objekt wünschen. So ein verwenden:

def (StyleParser = Object.new).process(text) 
    ... 
end 

def StyleParser.style_tag?(text) 
    ... 
end 

Oder alternativ:

class << (StyleParser = Object.new) 
    def process(text) 
    ... 
    end 

    def style_tag?(text) 
    ... 
    end 
end 

Aber wie @Azeem schon schrieb: für eine richtige Entscheidung, Sie mehr Kontext benötigen. Ich kenne das Innere von Prawn nicht genug, um zu wissen, warum Gregory diese besondere Entscheidung getroffen hat.

Verwandte Themen