Menu
CoddyTech

Pola Builder

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Ruby di Coddy. Pelajaran 48 dari 57.

Pola builder membuat object kompleks selangkah demi selangkah. Setiap langkah adalah method yang menyimpan satu pilihan dan mengembalikan builder, sehingga langkah-langkahnya dapat dirangkai; build memeriksa pilihan dan mengembalikan object yang sudah selesai:

class Pizza
  def initialize(size, toppings)
    @size = size
    @toppings = toppings
  end

  def to_s
    "#{@size} pizza with #{@toppings.join(", ")}"
  end
end

class PizzaBuilder
  def initialize
    @toppings = []
  end

  def size(value)
    @size = value
    self
  end

  def topping(name)
    @toppings << name
    self
  end

  def build
    raise ArgumentError, "size is required" if @size.nil?

    Pizza.new(@size, @toppings)
  end
end

puts PizzaBuilder.new.size("large").topping("cheese").topping("ham").build

Output:

large pizza with cheese, ham

Karena builder hanya membuat object di build, builder dapat memeriksa seluruh kombinasi sekaligus, seperti bagian yang wajib ada atau dua opsi yang tidak bisa digunakan bersama:

class TicketBuilder
  def seat(value)
    @seat = value
    self
  end

  def standing
    @standing = true
    self
  end

  def build
    raise ArgumentError, "seat and standing exclude each other" if @seat && @standing

    @standing ? "standing ticket" : "ticket for seat #{@seat || "any"}"
  end
end

puts TicketBuilder.new.seat("B7").build
puts TicketBuilder.new.standing.build
begin
  TicketBuilder.new.seat("A1").standing.build
rescue ArgumentError => e
  puts e.message
end

Output:

ticket for seat B7
standing ticket
seat and standing exclude each other

Bentuk Ruby yang umum memberikan builder kepada sebuah block. Class method membuat builder, meneruskannya dengan yield, lalu memanggil build di akhir:

class Email
  attr_accessor :to, :subject, :lines

  def self.compose
    email = new
    email.lines = []
    yield email
    email
  end

  def to_s
    "To: #{to}\nSubject: #{subject}\n\n#{lines.join("\n")}"
  end
end

mail = Email.compose do |e|
  e.to = "ada@x.io"
  e.subject = "Hi"
  e.lines << "Hello Ada,"
  e.lines << "see you soon."
end
puts mail

Output:

To: ada@x.io
Subject: Hi

Hello Ada,
see you soon.

Untuk beberapa nilai opsional, argumen kata kunci Ruby dengan nilai default sering kali sudah cukup. Builder berguna ketika bagian-bagiannya bisa berulang, urutannya penting, atau kombinasinya perlu diperiksa sebelum object dibuat:

Pizza.new(size: "large", crust: "thin")          # beberapa opsi: kata kunci

Query.new.from("users").where("age > 18").where("active = 1").limit(10).to_s
challenge icon

Tantangan

Mudah

Lengkapi PizzaBuilder dan Pizza. Langkah builder size(value), crust(value), dan topping(name) (dapat diulang) mengembalikan builder. build memunculkan ArgumentError dengan size is required jika ukuran belum diberikan, menggunakan crust classic jika belum dipilih, dan mengembalikan Pizza. Pizza#to_s mengembalikan large thin pizza with cheese, ham, atau small classic pizza with no toppings.

Setiap baris input adalah satu pesanan, seperti size=large crust=thin topping=cheese topping=ham. Kode yang disediakan mengirimkan setiap bagian ke builder secara berurutan dengan merangkainya, lalu mencetak pizza atau pesan error.

Tulis kodemu di pizza.rb dan pizza_builder.rb. main.rb berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

require_relative 'pizza'
require_relative 'pizza_builder'

# Kode input/output yang disediakan: biarkan apa adanya
input = []
while (line = gets)
  input << line.chomp
end
input.each do |line|
  builder = line.split.reduce(PizzaBuilder.new) do |b, part|
    step, value = part.split("=")
    b.public_send(step, value)
  end
  begin
    puts builder.build
  rescue ArgumentError => e
    puts e.message
  end
end
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Ruby online