Oluşturucu Deseni
Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 48 / 57.
builder deseni karmaşık bir nesneyi adım adım oluşturur. Her adım, bir seçimi depolayan ve oluşturucuyu döndüren bir yöntemdir; böylece adımlar zincirlenir. build seçimleri denetler ve tamamlanmış nesneyi döndürür:
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Çıktı:
large pizza with cheese, hamOluşturucu nesneyi yalnızca build içinde oluşturduğundan, zorunlu bir parça veya birlikte kullanılamayan iki seçenek gibi tüm birleşimi aynı anda kontrol edebilir:
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Çıktı:
ticket for seat B7
standing ticket
seat and standing exclude each otherYaygın bir Ruby biçimi, oluşturucuyu bir bloğa verir. Sınıf metodu oluşturucuyu oluşturur, ona yield eder ve sonunda build çağrısını yapar:
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Çıktı:
To: ada@x.io
Subject: Hi
Hello Ada,
see you soon.Bir avuç isteğe bağlı değer için Ruby'nin varsayılan değerlere sahip anahtar sözcük bağımsız değişkenleri çoğu zaman yeterlidir. Parçalar tekrarlanabildiğinde, sıra önemli olduğunda veya birleşimin nesne oluşturulmadan önce doğrulanması gerektiğinde builder kullanmak avantaj sağlar:
Pizza.new(size: "large", crust: "thin") # az seçenek: keywords
Query.new.from("users").where("age > 18").where("active = 1").limit(10).to_sGörev
KolayPizzaBuilder ve Pizza sınıflarını tamamla. Builder'ın size(value), crust(value) ve topping(name) (tekrarlanabilir) adımları builder'ı döndürür. build, boyut verilmediğinde ArgumentError hatasını size is required ile birlikte yükseltir, hiçbiri seçilmediğinde kabuk olarak classic kullanır ve bir Pizza döndürür. Pizza#to_s, large thin pizza with cheese, ham veya small classic pizza with no toppings döndürür.
Her girdi satırı size=large crust=thin topping=cheese topping=ham gibi bir sipariştir. Sağlanan kod, zincirleme yöntem çağrılarıyla her parçayı sırayla builder'a gönderir ve pizzayı veya hata mesajını yazdırır.
Kodun pizza.rb ve pizza_builder.rb dosyalarına yazılmalıdır. main.rb sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
require_relative 'pizza'
require_relative 'pizza_builder'
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
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
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıf TanımlamaÖrnek DeğişkenleriMetotlar ve selfto_s ve inspectÖzet - Kütüphane Kartı7Çok Biçimlilik ve Ördek Tiplemesi
Çok BiçimlilikÖrdek TiplemesiSoyut Metotlarcase ve SınıflarTekrar - Ödeme Yöntemleri2Erişimciler ve self
Okuyucular ve YazıcılarÖzel Setter'larMetotlarda selfKimlik ve EşitlikTekrar - Kişi Listesi5Kalıtım
Alt sınıflarMetotları geçersiz kılmasuper çağrısıis_a? ve üst sınıflarTekrar - Personel Maaşları8Özel Metotlar
Eşitlik ve hashOperatör Metotlarıİndeksleme ve EklemeÖzel KoleksiyonlarTekrar - Kesirler11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç Alma3Sınıf Metotları ve Değişkenleri
Sınıf MetotlarıSınıf Örnek DeğişkenleriSabitlerFabrika MetotlarıTekrar - Kupon KodlarıKendi başına pratik yap: Online Ruby derleyicisi