3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事は何

デザインパターンについて、Rubyでどのような使い方ができるかをまとめた記事です。
デザインパターン自体の解説は詳しく行いません。

Builerパターンとは

Builderパターンとは、生成するインスタンスへ渡すパラメータを段階的に組み立てることで、複雑なオブジェクトの生成を容易にするデザインパターンです。
詳しくはこちらをご覧ください。

Rubyでのコード例

以下のように、生成したいクラスの定義と、そのクラスを生成するBuilderクラスの実装を行います。
それぞれのメソッドでselfを返すようにすることで、メソッドチェーンでメソッドを書けるようにすることも可能です。

class Computer
  def initialize(cpu:, ram:, storage:)
    @cpu = cpu
    @ram = ram
    @storage = storage
  end

  def to_s
    "CPU: #{@cpu}, RAM: #{@ram}, Storage: #{@storage}"
  end
end

class ComputerBuilder
  def initialize
    @cpu = ''
    @ram = ''
    @storage = ''
  end

  def add_cpu(cpu)
    @cpu = cpu
    self
  end

  def add_ram(ram)
    @ram = ram
    self
  end

  def add_storage(storage)
    @storage = storage
    self
  end

  def build
    Computer.new(cpu: @cpu, ram: @ram, storage: @storage)
  end
end

builder = ComputerBuilder.new
computer = builder.add_cpu('Intel i9')
                .add_ram('32GB')
                .add_storage('1TB SSD')
                .build

puts computer
実行結果
CPU: Intel i9, RAM: 32GB, Storage: 1TB SSD

どのような時に使えるか

以下のようなときにBuilderパターンは便利です。

  • コンストラクタの種類が多く、コンストラクタに渡す値自体の計算が複雑な場合
  • 最終的に生成するオブジェクトを不変にしたい場合

例えば、以下のように与えられた辺の長さを元に、表面積や体積などの値を保持したデータオブジェクトを生成する場合などにBuilderパターンは有効に活用できます。

class Box
  attr_reader :length, :width, :height, :volume, :surface_area

  def initialize(length:, width:, height:, volume:, surface_area:)
    @length = length
    @width = width
    @height = height
    @volume = volume
    @surface_area = surface_area
  end

  def to_s
    "Length: #{@length}, Width: #{@width}, Height: #{@height}, Volume: #{@volume}, Surface Area: #{@surface_area}"
  end
end

class BoxBuilder
  def initialize
    @length = 0
    @width = 0
    @height = 0
  end

  def set_length(length)
    @length = length
    self
  end

  def set_width(width)
    @width = width
    self
  end

  def set_height(height)
    @height = height
    self
  end

  def calculate_volume
    @length * @width * @height
  end

  def calculate_surface_area
    2 * (@length * @width + @width * @height + @height * @length)
  end

  def build
    volume = calculate_volume
    surface_area = calculate_surface_area
    Box.new(length: @length, width: @width, height: @height, volume: volume, surface_area: surface_area)
  end
end

builder = BoxBuilder.new
box = builder.set_length(10)
            .set_width(5)
            .set_height(2)
            .build

puts box
実行結果
Length: 10, Width: 5, Height: 2, Volume: 100, Surface Area: 160
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?