Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Ruby: 条件を切り出していい感じのメソッド名を付けよう(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Ruby: 条件を切り出していい感じのメソッド名を付けよう(翻訳)

シンプル(かつ効果の高い)リファクタリング手法のひとつといえば、メソッドへの切り出しがあります。切り出したメソッドに名前を付ける手法は、コードの背後に潜むアイデアを示すうえで有用なツールです。

次のようには書かないこと

条件にステートメントをごちゃごちゃ書く。

class BrightonCoffeeShop
  def initialize(name)
    @name = name
  end

  def good?
    if @name == 'Starbucks' || @name == 'Costa' ||
       @name == "Barry's Caff"
      false
    elsif @name == 'Coffee@33' || @name == 'Small Batch'
      true
    else
      false
    end
  end
end

この実装が、nameが不明な場合にfalseを返すことはもう見え見えです。あなたがこの喫茶店で満足にくつろげるようにする唯一の方法は、わけのわからないルールを排除することです。

次のように書くこと

「メソッドの切り出し」リファクタリング手法を用いて、ロジックをprivateメソッドに移動し、コードのコンセプトを的確に表すメソッド名を付ける。

class BrightonCoffeeShop
  def initialize(name)
    @name = name
  end

  def good?
    clean? && local? && excellent_coffee?
  end

  private

  def clean?
    !filthy?
  end

  def excellent_coffee?
    ['Coffee@33', 'Small Batch'].include?(@name)
  end

  def filthy?
    @name == "Barry's Caff"
  end

  def local?
    !national_chain?
  end

  def national_chain?
    ['Starbucks', 'Costa'].include?(@name)
  end
end

そうすべき理由

メソッドを切り出して定義することで、メソッドに名前を付けます。上の#good?メソッドは、よい喫茶店かどうかを判断するための基準を示します。この新しいprivateメソッドは、クラスのドキュメントとしても機能します。

修正前のコードでは、「よい」喫茶店と「よくない」喫茶店のリストしかなく、このリストがどのように形成されたのかという知識も示されていませんでした。

このクラスに対する初歩的なリファクタリングとして、GOODBADという配列にそれぞれよい名前と悪い名前のリストを詰め込み、喫茶店のnameをそれでチェックするという方法もないわけではありません。しかしその方法では、その喫茶店がよい理由も悪い理由も見えなくなってしまうでしょう。しかもその理由こそが、このコードで最も重要な部分なのです。

修正後のコードでは、#clean?(清潔)や#local?(地元)といったポジティブな評価基準だけではなく、#filthy?(不潔)や#national_chain?(全国チェーン)といったネガティブな評価基準についても切り出しました。このおかげで、#good?メソッドのネガティブバージョンをprivateメソッドに用意しなくても済みます。少々やりすぎに思える部分かもしれませんが、このクラスでは満足の行く喫茶店に対する肯定的な評価の方を強く重視しているのですから、これによって有用なコンテキストが付け加えられます。

リファクタリングの手法が何であれ、リファクタリング前には最初の実装をカバーするよいテストをしっかり書いて、機能がうっかり変わらないようにしておきましょう。

そうするべきでない理由があるとすれば

上よりももっとシンプルな例であれば、このリファクタリングを行うまでもないかもしれません。しかしそれでもドキュメント作成の有用な手法でもあり、条件のロジックを明確化できます。

上よりもさらに複雑な場合(喫茶店に対して良否以外にも多くの要件を課すなど)は、個別の喫茶店をサブクラス化する形でリファクタリングするとよいかもしれません。

はてブより

Ruby: 条件を切り出していい感じのメソッド名を付けよう(翻訳)

この前後輩が長いifの条件を改行したいんだけど……って聞いてきたので、先頭揃えるのがよく見る気がするけど匂ってるのでメソッドに切り出そうって話した。結局ifをネストしてた。

2018/06/10 19:09

関連記事

Rubyのクラスメソッドがリファクタリングに抵抗する理由(翻訳)

Rails tips: テストから共通機能を切り出すリファクタリング(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。