2010-04-19 53 views
17

我目前正在通過格雷戈里布朗Ruby Best Practices書。早些時候,他正在談論重構相關類的輔助方法的某些功能,以及模塊上的某些方法,然後使用模塊extend self何時使用模塊以及何時使用某個類

在沒有看到之前,在google快速瀏覽之後,發現模塊上的extend self讓模塊上定義的方法可以互相看到,這很有道理。

現在,我的問題是,當你會做這樣的事情

module StyleParser 
    extend self 

    def process(text) 
    ... 
    end 

    def style_tag?(text) 
    ... 
    end 
end 

,然後引用它在測試中與

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

,而不是這樣呢?

class StyleParser 

    def self.process(text) 
    ... 
    end 

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

它是這樣,你可以使用它作爲一個混合?或者我還沒有看到其他原因?

回答

30

一個類應該用於需要實例化或需要跟蹤狀態的功能。模塊既可以用作將功能混合到多個類中的一種方式,也可以用作提供不需要實例化或追蹤狀態的一次性功能的方式。類方法也可以用於後者。

考慮到這一點,我認爲區別在於你是否真的需要一個班級。當你有一個需要一些單例功能的現有類時,類方法似乎更合適。如果你所做的只是單例方法,那麼將它作爲一個模塊來實現並通過模塊直接訪問它就更有意義了。

+1

正是我在找的:-) – 2010-04-20 00:30:07

-2

如果它是你想實例化的東西,請使用一個類。剩下的問題需要更多的上下文才能理解。

3

在這種特殊情況下,我可能不會使用類或模塊。

一個類是對象的工廠(注意複數)。如果您不想創建該類的多個實例,則不需要它存在。

模塊是多個對象共享的方法容器。如果您不將模塊混入多個對象,則不需要它存在。

在這種情況下,它看起來像你只是想要一個對象。因此,使用一個:

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

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

或者:

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

    def style_tag?(text) 
    ... 
    end 
end 

但作爲@Azeem已經寫:一個正確的決定,你需要更多的上下文。我對蝦的內部知識不夠了解,爲什麼Gregory會做出這樣的決定。

相關問題