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

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

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

当ブログではアフィリエイト広告を利用しています

コンストラクタからファクトリメソッドへ【リファクタリング Rubyエディションまとめ6】

こんにちは。

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

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

今回はその第6弾で「コンストラクタからファクトリメソッドへ」についてまとめました。
オリジナルの Ruby のサンプルコードを使って説明しています。

第5弾の「タイプコードからポリモーフィズムへ」のまとめはこちらです。
タイプコードからポリモーフィズムへ【リファクタリング Rubyエディションまとめ5】 - 銀行員からのRailsエンジニア

f:id:ysk_pro:20200520070559p:plain

サンプルコード

リファクタリング

文章での説明よりもコードを見た方が分かりやすいので、早速サンプルコードを見ていきましょう。
まずはリファクタリング前のコードです。

class Car
  def initialize(price)
    @price = price
  end

  def guarantee?
    false
  end
end

class ForeinCar < Car
  def guarantee?
    false
  end
end

class HighGradeCar < Car
  def guarantee?
    true
  end
end

Car(車)クラス、Carクラスを継承した ForeinCar(外車)クラス・HighGradeCar(高級車)クラスがあります。

imported = false
price = 200

car1 = if imported
         ForeinCar.new(price)
       elsif price > 100
         HighGradeCar.new(price)
       else
         Car.new(price)
       end
puts car1.guarantee? # -> true

作成するオブジェクトを決めるために条件分岐を使っています。また、複数箇所でオブジェクトを作成しており、同じ条件分岐が使われているとします。

このコードの問題点としては以下の点が挙げられます。

  • 条件分岐のコードが重複していること
  • 呼び出しているクラスと、オブジェクトが作られるクラス(ForeinCarなど)の結合度が強くなり、保守性が低くなっていること(例えば、ForeinCarクラスのクラス名や呼び出し方が変わると、呼び出し元のクラスも変更しなくてはいけなくなってしまいます)

リファクタリング

「コンストラクタからファクトリメソッドへ」を使ってリファクタリングしていきます。

リファクタリングはシンプルで、先ほどの Carクラスに、オブジェクト作成のためのクラスメソッドを1つ追加するのみです。

class Car
  def self.create(imported, price) # ファクトリメソッド
    if imported
      ForeinCar.new(price)
    elsif price > 100
      HighGradeCar.new(price)
    else
      new(price)
    end
  end
end

create がファクトリメソッドです。

次のように実行すると結果はリファクタリング前と同じになります。

car2 = Car.create(imported, price)
puts car2.guarantee?

オブジェクトの作成は全てファクトリメソッドで行うようにすることで、コードの重複はなくなり、クラス間の結合度も弱くすることができました。

「コンストラクタからファクトリメソッドへ」という名前は、呼び出し元からコンストラクタを呼び出していた(newしていた)ものをファクトリメソッドを呼び出すように変える、という意味のようです。

おわりに

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

リファクタリング Rubyエディションでは、この記事とは別のサンプルコードで丁寧に説明されていて分かりやすかったので、ご興味ある方は是非ご覧ください。

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

(追記)
第7弾として「サンドイッチメソッドの抽出」についてまとめました。
是非合わせてご覧ください。
ysk-pro.hatenablog.com