銀行員からのRailsエンジニア

銀行員からのRailsエンジニア

銀行員から転身したサービス作りが大好きなRailsエンジニアのブログです。個人で開発したサービスをいくつか運営しており、今も新しいサービスを開発しています。転職して日々感じていること、個人開発サービス運営のことなどを等身大で書いていきます。

サンドイッチメソッドの抽出【リファクタリング Rubyエディションまとめ7】

こんにちは。

最近 リファクタリング Rubyエディション を読みました。本書はリファクタリングの様々なパターンRubyのサンプルコードを使って解説している名著です。

実務でも活かせそうなパターンが多くあったので、いいなと思ったパターンを1つずつブログにまとめています。

今回はその第7弾で「サンドイッチメソッドの抽出」についてまとめました。
オリジナルの Ruby のサンプルコードを使って説明しています。

第6弾の「コンストラクタからファクトリメソッドへ」のまとめはこちらです。
コンストラクタからファクトリメソッドへ【リファクタリング Rubyエディションまとめ6】 - 銀行員からのRailsエンジニア

f:id:ysk_pro:20200524151911p:plain

サンドイッチメソッドの抽出 とは

使えるタイミング

ほとんど内容が同じメソッドが複数あり、違いがメソッドの途中(最初や最後ではない)にある場合に有効なリファクタリングです。

リファクタリング方法

Rubyのブロックを使用します。
差異の部分をブロック呼び出し(yield)にしてメソッドを定義します。
呼び出し元は、差異の部分をブロックで渡してメソッドを呼び出します。

サンドイッチメソッドの抽出という名前の通り、共通部分でサンドイッチしているイメージですね。

文章での説明よりサンプルコードを見た方が理解しやすいので、サンプルコードを見ていきましょう。

サンプルコード

リファクタリング

まずはリファクタリング前のコードです。

class Person
  def sunny_day_activities
    puts 'work from home'
    puts 'running' # 晴れの日はランニングする
    puts 'play games'
  end

  def rain_day_activities
    puts 'work from home'
    puts 'taking a nap' # 雨の日は外に出たくないので昼寝する
    puts 'play games'
  end
end

かなりシンプルなクラスですね。

次のように実行すると

person1 = Person.new
person1.sunny_day_activities
person1.rain_day_activities

次の結果になります。

work from home
running
play games
work from home
taking a nap
play games

sunny_day_activities メソッドと、rain_day_activities メソッドは、それぞれの 2つ目の puts 以外ほとんど同じなので共通化したいですね。

リファクタリング

「サンドイッチメソッドの抽出」を使ってリファクタリングをすると下記のようになります。

class Person
  def activities
    puts 'work from home'
    yield
    puts 'play games'
  end
end

次のように実行すると、先ほどと実行結果は同じになります。

person2 = Person.new
person2.activities { puts 'running' }
person2.activities { puts 'taking a nap' }

差異のある部分をブロックで渡し、yield でブロックを実行しています。

いい感じに共通化できましたね。

おわりに

ここまでお読みいただきありがとうございます。

リファクタリング Rubyエディションでは、このブログよりもリアルのコードで解説しており分かりやすかったので、ご興味ある方は是非ご覧ください。

次回はまた違うパターンをまとめていきます!

(追記)
第8弾として「抽象スーパークラスからモジュールへ」についてまとめました。
是非合わせてご覧ください。
ysk-pro.hatenablog.com