「Rubyによるデザインパターン」の読書メモです。
ビルダ (Builder) クラスが担当するのは、ある複雑なオブジェクトのコンポーネントの組み立てです。各ビルダには新しいオブジェクトに対してステップごとに構成を指示するインターフェースを持っています。
test.rb
class Computer
attr_accessor :display
attr_accessor :motherboard
attr_reader :drives
def initialize(display=:crt, motherboard=Motherboard.new, drives=[])
@motherboard = motherboard
@drives = drives
@display = display
end
end
class CPU
end
class BasicCPU < CPU
end
class TurboCPU < CPU
end
class Motherboard
attr_accessor :cpu
attr_accessor :memory_size
def initialize(cpu=BasicCPU.new, memory_size=10000)
@cpu = cpu
@memroy_size = memory_size
end
end
class Drive
attr_reader :type # :hard_disk, :cd, :dvd
attr_reader :size # 単位は MB
attr_reader :writable
def initialize(type, size, writable)
@type = type
@size = size
@writable = writable
end
end
class ComputerBuilder
attr_reader :computer
def initialize
@computer = Computer.new
end
def turbo(has_turbo_cpu=true)
@computer.motherboard.cpu = TurboCPU.new
end
def display=(display)
@computer.display = display
end
def memory_size=(size_in_mb)
@computer.motherboard.memory_size = size_in_mb
end
def add_cd(writer=false)
@computer.drives << Drive.new(:cd, 760, writer)
end
def add_dvd(writer=false)
@computer.drives << Drive.new(:cd, 760, writer)
end
def add_hard_disk(writer=false)
@computer.drives << Drive.new(:dvd, 4700, writer)
end
end
builder = ComputerBuilder.new
builder.turbo
builder.add_cd(true)
builder.add_dvd
builder.add_hard_disk(true)
p builder.computer
出力結果
$ ruby test.rb
#<Computer:0x00007fd3da8b3c78 @motherboard=#<Motherboard:0x00007fd3da8b3c50 @cpu=#<TurboCPU:0x00007fd3da8b3bd8>, @memroy_size=10000>, @drives=[#<Drive:0x00007fd3da8b3bb0 @type=:cd, @size=760, @writable=true>, #<Drive:0x00007fd3da8b3b88 @type=:cd, @size=760, @writable=false>, #<Drive:0x00007fd3da8b3b60 @type=:dvd, @size=4700, @writable=true>], @display=:crt>
まとめ
Builderパターンの考え方は、オブジェクトを作り出すのが難しい場合や、オブジェクトを構成するのに大量のコードを書かなければいけない場合に、それらの生成のためのコードを別のクラス、すなわちビルダに分離するというものです。