Tbpgr Blog

Ruby プログラマ tbpgr(てぃーびー) のブログ

書籍 リファクタリング−プログラマーの体質改善 | オブジェクト間での特性の移動 | メソッドの移動:Move Method

内容

リファクタリング

メソッドの移動:Move Method

適用ケース要約

メソッドが、自分のクラスよりも他クラスの機能を使ったり、他クラスから利用されたりする。
今はそうでなくても、そうなりつつある。

適用内容要約

メソッドをもっともよく使っているクラスに同じ内容の新メソッドを作る。
古いメソッドは、このメソッドに処理を委ねるか、完全に取り除く。

適用詳細

オブジェクトAで使用されているメソッドBで、オブジェクトCの内容ばかり操作しているような
場合はメソッドBをオブジェクトCに移動します。

サンプル

とあるプログラマーTbpgとBeckが居るとします。
Tbpgは難しいコードがあるたびにBeckを自席に呼んでコーディングしてもらっていました。
ある時、毎回BeckをつれてくるぐらいならBeckに処理を担当してもらうことにしました。

前者がリファクタリング前、後者がリファクタリング後にあたります。

サンプルコード

リファクタリング

# encoding: Shift_JIS

NORMAL_LEVEL="normal"
DIFFICULT_LEVEL="difficult"

class Tbpg

  def think()
    puts "Tbpgは問題を考えています"
  end
  
  def flash()
    puts "Tbpgは閃きました"
  end
  
  def resolve()
    puts "Tbpgは問題を解決しました"
  end

  def coding(level)
    if level==NORMAL_LEVEL
      normal_coding
    elsif level==DIFFICULT_LEVEL
      difficult_coding
    else
      raise 'error'
    end
  end
  
  private
  def normal_coding()
    think
    flash
    resolve
  end
  
  private
  def difficult_coding()
    beck=Beck.new
    beck.think
    beck.flash
    beck.resolve
  end
end

class Beck
  def think()
    puts "Beckは問題を考えています"
  end
  
  def flash()
    puts "Beckは閃きました"
  end
  
  def resolve()
    puts "Beckは問題を解決しました"
  end
end

tbpg=Tbpg.new
tbpg.coding(NORMAL_LEVEL)
tbpg.coding(DIFFICULT_LEVEL)

リファクタリング

# encoding: Shift_JIS

NORMAL_LEVEL="normal"
DIFFICULT_LEVEL="difficult"

class Tbpg

  def think()
    puts "Tbpgは問題を考えています"
  end
  
  def flash()
    puts "Tbpgは閃きました"
  end
  
  def resolve()
    puts "Tbpgは問題を解決しました"
  end

  def coding(level)
    if level==NORMAL_LEVEL
      normal_coding
    elsif level==DIFFICULT_LEVEL
      Beck.new.coding
    else
      raise 'error'
    end
  end
  
  private
  def normal_coding()
    think
    flash
    resolve
  end
end

class Beck
  def think()
    puts "Beckは問題を考えています"
  end
  
  def flash()
    puts "Beckは閃きました"
  end
  
  def resolve()
    puts "Beckは問題を解決しました"
  end

  def coding()
      think
      flash
      resolve
  end
end

tbpg=Tbpg.new
tbpg.coding(NORMAL_LEVEL)
tbpg.coding(DIFFICULT_LEVEL)

▼出力結果(共通)

Tbpgは問題を考えています
Tbpgは閃きました
Tbpgは問題を解決しました
Beckは問題を考えています
Beckは閃きました
Beckは問題を解決しました
解説

▼difficult_coding
リファクタリング前のdifficult_codingメソッドはほとんどの処理を
Beckが行っていました。
メソッドBeckに移動することで、適切な責務を割り当てることが出来ました。