2010-11-02 42 views
7

當我閱讀更多關於Ruby元編程的內容時,大多數時候我們發現至少有兩種解決方案來解決問題。請看下面兩個例子:類與模塊在設計Ruby API?

class Base 
    def self.has_many(*args) 
    # ... 
    end 
end 

class Student < Base 
    has_many :books 
end 

另一種風格:

module Base 
    def self.included(klass) 
    klass.extend ClassMethods 
    end 

    module ClassMethods 
    def has_many(*args) 
     # ... 
    end 
    end 
end 

class Student 
    include Base 

    has_many :books 
end 

但是,當我們設計的API,我們必須決定使用哪一個,但我想問一下您的想法和一些大多數人已經在他們的圖書館中實施的最佳實踐。

回答

5

如果你的API將提供的基本功能,這將通過客戶端進行擴展,那麼你應該更喜歡繼承

如果您的API將使用各自的基本功能擴展各種客戶端,那麼您應該使用組合

2

你對這個問題有很多理論。

我傾向於更喜歡構圖,因爲它使行爲更加可重用,但是如果您看看Rails,則每次需要在數據庫中創建對象時,都必須劃分ActiveRecord :: Base類的子類。如果你看看DataMapper,它恰恰相反,因爲他們只是要求你包含DataMapper :: Resource。

繼承VS組成(通過模塊)是一個很大的話題,你必須問自己一個問題將歸結爲:我如何能實現我公司提供的部件和其他用戶現有的代碼庫之間的較大分開呢?

1

Ruby僅支持單繼承。因此,如果API客戶端必須繼承您的基類,他們將失去繼承其他類的能力。使用模塊包含你可能會得到如下代碼:

class Student < Person 
    include Base 
    has_many :books 
end 

因此,您可以「繼承」Person和Base。

然而,經典的繼承語法看起來更自然,不那麼「神奇」