我是Ruby的新手,我遇到了代码组织问题。
我有一个名为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 = Movie.new("Titanic", "1997", "0120338")
movie.imdb_url(movie.movieID)
组织此代码的正确方法是什么?
答案 0 :(得分:2)
如果要在多个类中使用它,您只需要将此代码提取到单独的模块中。然而,我可以重申将大型模型拆分成几个小块的愿望。
例如,您可以建立一个包含类必须遵守的协议,并将其留给id来自的包含类。在以下示例中,包含类必须实现方法imdb_id
,该方法应返回将用于url的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
然而,我必须说,我发现整个提取到mixins有点笨拙。另一种方法是创建一个知道如何构建url但不知道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。
答案 1 :(得分:1)
关于你的评论我会说,IMDBMovieInfo模块不应该有一个需要movieID的函数。您可以将它移动到您的Movie类。