打破Ruby类的枯燥
我有一些类似的课程:打破Ruby类的枯燥,ruby,design-patterns,Ruby,Design Patterns,我有一些类似的课程: class Word def initialize (file_name) load_file(file_name) end def pick_first_word(score) #get first word end private def load_file(file_name) #load the file end end class MyClass < SomeOther def initiali
class Word
def initialize (file_name)
load_file(file_name)
end
def pick_first_word(score)
#get first word
end
private
def load_file(file_name)
#load the file
end
end
class MyClass < SomeOther
def initialize (file_name)
@word = Word.new(file_name)
end
def pick
@word.pick_first_word
end
#some other code
end
dosomething = MyClass.new("words.txt")
dosomethingelse = MyClass.new("movies.txt")
这个实现看起来不是很可伸缩 试试FileMagic库
gem install ruby-filemagic
例如:
require 'filemagic'
type = FileMagic.new.file file_name
这都是一个权衡的问题——在这种情况下,您只需要足够的复杂性来处理合理数量的案例 如果只有两种选择,我认为If语句看起来不错。一个(又称switch语句)可以是DRYer,您可能想显式地说“movie.txt”,例如 或者,如果您不喜欢将case语句放在parens中,那么可以为文件名提取一个
class\u方法,尽管这很有趣
如果您的多态类集变得更大,您可能会从查找表中获得更多好处:
class_for_file_name = {
"word.txt" => Word,
"movie.txt" => Movie,
"sandwich.txt" => Sandwich,
}
@word = class_for_file_name[file_name].new(file_name)
当然,可能您过于简单化了,您真的想打开文件扩展名,而不是文件名,您可以通过file.extname(file\u name)
获得文件扩展名
您还可以更进一步,询问每个具体类是否处理该文件名;这感觉更像是面向对象的——它将关于Foo的知识放在Foo类中——但可以说更复杂:
class Word
def self.good_for? file_name
file_name == "word.txt"
end
end
class Movie
def self.good_for? file_name
file_name == "movie.txt"
end
end
...
def class_for_file_name file_name
[Word, Movie].detect{|k| k.good_for? file_name}
end
顺便说一句,这个问题或多或少符合所谓的设计模式;您可能想查看它,看看它的任何分析是否能激发您的灵感。这似乎是“策略”设计模式的一个很好的候选者:有没有办法检测到与文件本身的差异?没有,没有。但如果有帮助的话,我愿意在传递文件名的同时传递其他内容。文件名甚至可以保留在实际类中
class_for_file_name = {
"word.txt" => Word,
"movie.txt" => Movie,
"sandwich.txt" => Sandwich,
}
@word = class_for_file_name[file_name].new(file_name)
class Word
def self.good_for? file_name
file_name == "word.txt"
end
end
class Movie
def self.good_for? file_name
file_name == "movie.txt"
end
end
...
def class_for_file_name file_name
[Word, Movie].detect{|k| k.good_for? file_name}
end