1

私はこれらのようないくつかのクラスを持っています:

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")

Wordそのため、ファイルを読み取り、最初の単語を選択するためのクラスがあります。それと同じように、別のクラス、たとえばMovies、との独自の実装を持つload_fileクラスが必要pick_first_wordです。に送信するファイルの種類によってこれを制御したいMyClass

質問

送信するファイルの種類に基づいて正しいクラスを開始するようにinitializeメソッドを変更する良い方法は何ですか。MyClassファイル名に対して if/else で実行できますが、あまりスケーラブルではないようです。

initializeメソッドをこれに変更するよりも、これを行うためのより良い方法はありMyClassますか?

  def initialize (file_name)
    if (file_name == "word.txt")
      @word = Word.new(file_name)
    else
      @word = Movie.new(file_name)
  end

この実装はあまりスケーラブルではないようです。

4

2 に答える 2

0

それはすべてトレードオフの問題です。この場合、適切な数のケースを処理するのに十分な複雑さが必要です。

選択肢が 2 つしかない場合、if ステートメントは問題ないように見えると思います。「case」ステートメント(別名 switch ステートメント) は DRYer にすることができ、明示的に「movie.txt」と言うことができます。

@word = (case file_name
  when "word.txt"
    Word
  when "movie.txt"
    Movie
  else
    raise "Unknown file name #{file_name}"
  end).new(file_name)

class_for_file_nameまたは、括弧内に case ステートメントを入れたくない場合は、メソッドを抽出しますが、それはかなり楽しいものです。

ポリモーフィック クラスのセットが大きくなると、ルックアップ テーブルからより多くのマイレージが得られる可能性があります。

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_name)

さらに凝って、各具象クラスがこのファイル名を処理するかどうかを尋ねることもできます。これは OO のように感じます -- foo クラスの中に foos についての知識を置きます -- しかし間違いなくもっと複雑です:

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    

ところで、この問題は多かれ少なかれAbstract Factoryと呼ばれる設計パターンに当てはまります。あなたはそれを調べて、その分析のいずれかがあなたを刺激するかどうかを確認したいかもしれません.

于 2013-04-17T17:46:12.333 に答える
-1

FileMagic ライブラリを試してください。

gem install ruby-filemagic

例:

require 'filemagic'
type = FileMagic.new.file file_name
于 2013-04-17T17:24:03.617 に答える