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

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

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

【Rubyによるデザインパターンまとめ12】ビルダパターン

コードの品質向上のため、Rubyデザインパターンを解説した名著である Rubyによるデザインパターン で紹介されているデザインパターンを1つずつまとめており、今回が第12弾です。(毎週1つが目標です!)

前回の記事(ファクトリメソッドパターンのまとめ)はこちらです。
【Rubyによるデザインパターンまとめ11】ファクトリメソッドパターン - 銀行員からのRailsエンジニア

言葉での説明よりもコードを見た方が分かりやすいので、サンプルコードでの説明をメインにしています。

今回は ビルダ(Build)パターン についてまとめました。

f:id:ysk_pro:20200222105019p:plain

ビルダパターンとは

オブジェクトを作るのに大量のコードを書かなければいけない場合などに、オブジェクトの生成のためのコードを別のクラス(ビルダクラス)に分離するパターンです。

つまり、オブジェクトの生成手順(コード上ではコンストラクタ)を外出しします。複雑なオブジェクトの生成手順を分離することで、構造がシンプルになり、再利用性も高めることができます

文章の説明よりも実際のコードを見た方が分かりやすので、以下のサンプルコードをご覧ください。

サンプルコード

ユーザーのオブジェクトを作るプログラムを考えてみましょう。

まずはビルダパターンを使わずに実装してみます。

class User
  attr_accessor :first_name, :last_name, :birthday, :gender, :status, :email, :password

  def initialize(first_name, last_name, birthday, gender, status, email, password)
    @first_name = first_name
    @last_name = last_name
    @birthday = birthday
    @gender = gender
    @status = status
    @email = email
    @password = password
  end
end

このように実行すると、

user = User.new('テスト', '太郎', '1991-08-11', 1, 1, 'test@example.com', 'pass1234')
p user

次のようにオブジェクトができていることが分かります。

#<UserBuilder:0x00007f911d911f08 @user=#<User:0x00007f911d911ee0 @first_name="テスト", @last_name="太郎", @gender=1, @status=1, @email="test@example.com", @password="pass1234">>

このコードはオブジェクトの生成時に大量のパラメータを渡す必要があり、今後新しいパラメータが追加された場合などには、どんどん複雑になり分かりにくくなってしまいます

これをビルダパターンを使って書き換えてみましょう。

class User
  attr_accessor :first_name, :last_name, :birthday, :gender, :status, :email, :password
end

class UserBuilder
  attr_reader :user

  def initialize
    @user = User.new
  end

  def set_name(first_name, last_name)
    @user.first_name = first_name
    @user.last_name = last_name
  end

  def set_birthday(birthday)
    @user.birthday = birthday
  end

  def set_as_man
    @user.gender = 1
  end

  def set_as_woman
    @user.gender = 2
  end

  def set_as_active
    @user.status = 1
  end

  def set_login_credectiols(email, password)
    @user.email = email
    @user.password = password
  end
end

次のように実行すると先ほどと同じ結果となり、ユーザーのオブジェクトを作ることができました。

user_builder = UserBuilder.new
user_builder.set_name('テスト', '太郎')
user_builder.set_birthday('1991-08-11')
user_builder.set_as_man
user_builder.set_as_active
user_builder.set_login_credectiols('test@example.com', 'pass1234')
user = user_builder.user
p user

こうすることでオブジェクトの生成手順が分かりやすくなり、今後ユーザーと近いオブジェクトを作る際にはビルダクラスを共通化することもできるので再利用性も高まりました

今回のサンプルコードは、こちらのサイトを参考にさせていただきました。英語ですがとても分かりやすくて勉強になりました。
Builder design pattern in Ruby - kkempin’s dev blog - Medium

おわりに

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

Rubyによるデザインパターン の中でも、ビルダクラスを使ってリファクタリングしていく形式で分かりやすかったので、ご興味ある方は是非合わせてご覧ください。

Rubyによるデザインパターン

Rubyによるデザインパターン

次回は、インタプリタInterpreter)パターンをまとめます。

来週も頑張ります!

(追記)
インタプリタパターンについてまとめました!
是非合わせてご覧ください。
ysk-pro.hatenablog.com