Ruby
オブジェクト指向
リファクタリング
RubyOnRails
oop

リファクタリングに使える「聞くな、言え」の法則

Rubyのリファクタリング:「聞くな、言え」の法則を読んで、自分なりに消化してまとめました。

「聞くな、言え」の法則

なにか?

  • (特にpublicメソッドの中においては、)if/elseなどで条件分岐(聞く/確認する)をせず、外部からメソッドを呼び出す(言う)

メリットは?

  • SRPを保ちやすくなる
    • if/elseは条件が増えるとその分だけ処理が複雑になり、コードも長くなりがち
    • ひとつの関数内でいろいろなことをし始めると、デバックしにくく、バグの温床となる
  • 可読性や再利用性が高くなり、OOPらしいコードになる。

サンプルコード1

bad_sample_1.erb
# viewでよくあるやつ
<% if current_user.admin? %>
  <%= current_user.admin_welcome_message %>
<% else %>
  <%= current_user.user_welcome_message %>
<% end %>
better_sample_1.html.erb
# ただメソッドを読んでいる
<%= current_user.welcome_message %>
better_sample_helper_1.rb
# ヘルパーなどに切り出す
def welcome_message
  if current_user.admin?
    current_user.admin_welcome_message
  else
    current_user.user_welcome_message
  end
end

サンプルコード2

bad_sample_2.html.rb
class PlayMusic
  def play_music
    # ユーザーの所属するコースをいちいち確認して(聞いて)いる
    if user.is_a?(ViolinCourse)
      user.play_music(musical_score)
    end
  end
end
better_sample_2.rb
class PlayMusic
  def play_music
    # 単に値を投げる(言う)
    user.play_music(musical_score)
  end
end

class ViolinCourse
  def play_music(musical_score)
    do_something
  end
end

class GuitarCourse
  def play_music(musical_score)
    do_something
  end
end

class DrumCourse
  def play_music(musical_score)
    do_something
  end
end

サンプルコード3

bad_sample_3.rb
def make_lesson_plan
  ... #長い処理
  # 場合分けでlesson_typeに入る値を決めている
  if hogehoge
    lesson_plan = "Violin"
  elsif fugafuga
    lesson_plan = "Guitar"
  else
    lesson_plan = "I do not know"
  end
  ... #長い処理
end

better_sample_3.rb
def make_lesson_plan
  ... #長い処理
    lesson_plan = set_lesson_plan
  ... #長い処理
end

private
  def set_lesson_plan
    if hogehoge
      "Violin"
    elsif fugafuga
      "Guitar"
    else
      "I do not know"
    end
  end

参考