Tbpgr Blog

Recruiting Operations tbpgr(てぃーびー) のブログ

書籍 リファクタリング−プログラマーの体質改善 | メソッド呼び出しの単純化 | Factory Methodによるコンストラクタの置き換え

内容

リファクタリング

Factory Methodによるコンストラクタの置き換え

適用ケース要約

オブジェクトを生成する際に、単純な生成以上のことをしたい

適用内容要約

ファクトリメソッドを使って、コンストラクタを置き換える

適用詳細

インスタンスごとにタイプコードで処理を分けているような場合、Factory Methodでサブクラスの生成を
隠蔽することを検討します。

サンプル

ゲーム機クラスがあり、リファクタリング前は機種タイプでインスタンスの種類を管理しています。
ここでFactory Methodを導入します。

サンプルコード

リファクタリング

# encoding: Shift_JIS

class Game
  attr_accessor:game_type
  PS3=0
  WII=1
  DS=2
  PS_VITA=3
  
  def initialize(game_type)
    @game_type=game_type
  end
  
  def play()
    case @game_type
    when PS3
      puts "PS3で遊んでいます"
    when WII
      puts "WIIで遊んでいます"
    when DS
      puts "DSで遊んでいます"
    when PS_VITA
      puts "VITAで遊んでいます"
    else
      ralse "error"
    end
  end
  
end

game_types=[Game::PS3,Game::WII,Game::DS,Game::PS_VITA]

game_types.each {|game_type|
  game = Game.new(game_type)
  game.play
}

リファクタリング

# encoding: Shift_JIS

class Game
  private
  def initialize()
  end
  
  def self.get_game_hard(class_name)
    clazz=eval "#{class_name}"
    clazz.new
  end
  
  def play()
    raise "error"
  end
end

class Ps3 < Game
  def play()
    puts "PS3で遊んでいます"
  end
end

class Wii < Game
  def play()
    puts "Wiiで遊んでいます"
  end
end

class Ds < Game
  def play()
    puts "DSで遊んでいます"
  end
end

class PsVita < Game
  def play()
    puts "PS Vitaで遊んでいます"
  end
end

game_hards=["Ps3","Wii","Ds","PsVita"]

game_hards.each {|game_hard|
  game = Game.get_game_hard(game_hard)
  game.play
}

出力(リファクタリング後)

PS3で遊んでいます
Wiiで遊んでいます
DSで遊んでいます
PS Vitaで遊んでいます