2012-03-06 55 views
3

我決定深入研究Rails的ActiveRecord代碼,試圖弄清楚它的一些工作原理,並且很驚訝地看到它包含許多模塊,這些模塊似乎都包含在內到ActiveRecord :: Base。應用ActiveRecord如何將模塊用於其他Ruby項目

我知道Ruby模塊提供了一種將相關和可重用方法分組的方法,可以將其混合到其他類中以擴展其功能。

但是,大多數ActiveRecord模塊看起來都非常特定於ActiveRecord。似乎在某些模塊中引用了實例變量,表明模塊意識到整個ActiveRecord類和其他模塊的內部。

這讓我想知道ActiveRecord是如何設計的以及如何將這種邏輯應用於其他Ruby應用程序。

這是一種常見的「設計模式」,將大型類拆分成其他模塊,這些模塊在其他地方不是真正可重用的,只是爲了拆分類文件?當模塊使用可能由不同模塊或類的一部分定義的實例變量時,它被認爲是好的還是壞的設計?

如果一個類可以有很多方法,並且將它們全部定義在一個文件中會變得很麻煩,那麼簡單地重新打開其他文件中的類並定義其中的更多方法會有多大意義?

在我正在開發的命令行應用程序中,我有幾個可以執行各種功能的類,但是我有一個頂級類爲整個應用程序提供了一個API - 我發現該類正在陷入停滯狀態有很多方法可以將工作交給其他課程,就像粘在一起的粘合劑一樣。我猜想我想知道如果將某些相關方法拆分爲模塊或者在不同的代碼文件中重新打開該類是否合理?或者還有什麼我沒有想到的?

回答

3

我創建了很多模塊,我並不打算高度可重用。它使得更容易孤立地測試一組相關的方法,並且如果類只有幾百行而不是幾千行,則它們更具可讀性。與往常一樣,需要平衡一下。

我還創建了一些模塊,期望包含類定義實例方法,以便模塊上定義的方法可以使用它們。我不會說這是非常優雅的,但如果您只是在幾個課程之間共享代碼並將其良好記錄,則這是可行的。你也可以拋出一個異常,如果類定義你想要的方式:

module Aggregator 
    def aggregate 
    unless respond_to?(:collection) 
     raise Exception.new("Classes including #{self} must define #collection") 
    end 
    # ... 
    end 
end 

我會多出很多猶豫依賴於共享實例變量。

我在重新打開課程時看到的最大問題是管理您的源代碼。你會最終在不同的目錄中有aggregator.rb的多個副本嗎?這些文件的加載順序是否確定,是否會影響類中的覆蓋或調用方法?至少在模塊中,包含順序在源代碼中是明確的。


更新:在評論,斯蒂芬被問及考驗這個的意思包含在類的模塊。

RSpec提供shared_examples作爲測試共享行爲的便捷方式。您可以在一個共享上下文定義模塊的行爲,並宣佈每個包括類也應表現出的行爲:

# spec/shared_examples/aggregator_examples.rb 
shared_examples_for 'Aggregator' do 
    describe 'when aggregating records' do 
    it 'should accumulate values' do 
     # ... 
    end 
    end 
end 

# spec/models/model_spec.rb 
describe Model 
    it_should_behave_like 'Aggregator' 
end 

即使你不使用RSpec的,你仍然可以創建一個簡單的stub類包括您的模塊,然後針對該類別的實例編寫測試:

# test/unit/aggregator_test.rb 
class AggregatorTester 
    attr_accessor :collection 

    def initialize(collection) 
    self.collection = collection 
    end 

    include Aggregator 
end 

def test_aggregation 
    assert_equal 6, AggregatorTester.new([1, 2, 3]).aggregate 
end 
+0

相關方法的測試是另一個想法。你如何測試與另一個類相關的模塊中的方法?你是否在測試中創建了一個'準系統'類並在其中包含了模塊? – 2012-03-06 22:57:09

+0

我在回答中增加了一些註釋。 – Brandan 2012-03-06 23:31:09

相關問題