2013-10-21 37 views
0

我對Ruby相當陌生,並且存在代碼組織問題。引用mixin中的類屬性

我有一個叫做Movie的類,它包含一個名爲IMDBMovieInfo的模塊。

class Movie 

    include IMDBMovieInfo 
    attr_accessor :name 
    attr_accessor :year 
    attr_accessor :movieID 
end 

IMDBMovieInfo有它接受movieID並用它來建立一個IMDB URL的方法:

module IMDBMovieInfo 
    def imdb_url() 
     "http://www.imdb.com/title/tt#{self.movieID}/" 
    end 
end 

這裏的問題是我不知道我應該被引用在電影類的東西,因爲IMDBMovieInfo不知道那個類,並且不應該。我可以添加一個電影ID的說法,但後來如果你不知道的電影對象,你會做這一點,這沒有任何意義:

movie = Movie.new("Titanic", "1997", "0120338") 
movie.imdb_url(movie.movieID) 

什麼是正確的做法組織這個代碼?

+0

你爲什麼要創建IMDBMovieInfo模塊?那些打算使用的地方還有哪些?那些其他類也有一個movieID? – FlyingFoX

+0

@FlyingFoX不,他們可能不會,這就是爲什麼我知道這是一個問題。 IMDBMovieInfo執行與電影對象和IMDB相關的任務。我覺得我不應該用像這樣的額外方法重載Movie類。 – Andrew

+0

安德魯,你是對的,你不應該在模塊中引用類中的對象。它會起作用,但是在其他地方限制了模塊的用處,所以你應該把模塊的內容放在類中。你所需要做的就是把「沒有意義的」改變爲「完美無缺」。 –

回答

2

如果您要在多個類中使用它,則只需將此代碼提取到單獨的模塊中即可。然而,我可以重申希望將一個大型模型分成幾個小塊。

例如,您可以建立一個協議,包含的類必須遵守並將其留給包含id的包含類。在下面的例子中,包括類必須實現它應該返回將被用於該URL的ID的方法imdb_id

module IMDBMovieInfo 
    def imdb_id 
    raise NotImplementedError, 'including class needs to override imdb_id' 
    end 

    def imdb_url 
    "http://www.imdb.com/title/tt#{imdb_id}/" 
    end 
end 

class Movie 
    include IMDBMovieInfo 

    def imdb_id 
    self.movieID 
    end 

    attr_accessor :name 
    attr_accessor :year 
    attr_accessor :movieID 
end 

# In another classs 
# (suppose IMDB lists computer games in the future) 
class ComputerGame 
    include IMDBMovieInfo 

    def imdb_id 
    self.gameID 
    end 

    attr_accessor :name 
    attr_accessor :year 
    attr_accessor :gameID 
end 

我必須然而說,我覺得這是整個提取到混入有點笨拙。另一種方法是創建一個知道如何建立一個網址,但不要在那裏ID來自於一個實用工具類:

class IMDBUtil 
    def initialize(imdb_id) 
    @imdb_id = imdb_id 
    end 

    def imdb_url 
    "http://www.imdb.com/title/tt#{@imdb_id}/" 
    end 
end 

class Movie 
    include IMDBMovieInfo 

    def imdb_url 
    IMDBUtil.new(self.movieId).imdb_url 
    end 

    attr_accessor :name 
    attr_accessor :year 
    attr_accessor :movieID 
end 

爲了總結這件事,這裏有一個great blog post from CodeClimate on how to refactor fat Rails models

+0

我不相信你需要任何'self.'。 –

+0

@CarySwoveland這是正確的,但他們不傷害,我把它們包括在內,因爲這是問題中使用的符號,併爲了讓海報更容易理解。 –

1

關於你的評論我會說,IMDBMovieInfo模塊不應該有一個需要movieID的函數。你可以將它移動到你的電影類。