نمط الباني
جزء من قسم البرمجة كائنية التوجه في رحلة Ruby على Coddy. الدرس 48 من 57.
ينشئ نمط المنشئ كائنًا معقدًا خطوةً بخطوة. كل خطوة هي طريقة تخزّن خيارًا واحدًا وتُرجع المنشئ، ولذلك تتسلسل الخطوات؛ تتحقق build من الخيارات وتُرجع الكائن المكتمل:
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الناتج:
large pizza with cheese, hamلأن أداة البناء لا تُنشئ الكائن إلا في build، يمكنها التحقق من المجموعة كاملةً دفعةً واحدة، مثل جزء مطلوب أو خيارين لا يمكن استخدامهما معًا:
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الناتج:
ticket for seat B7
standing ticket
seat and standing exclude each otherيتولى كتلةً عادةً في Ruby مهمةَ البناء. تنشئ طريقة الصنف أداة البناء، وتمررها إلى الكتلة، وتستدعي build في النهاية:
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الناتج:
To: ada@x.io
Subject: Hi
Hello Ada,
see you soon.بالنسبة إلى عدد قليل من القيم الاختيارية، غالبًا ما تكون معاملات الكلمات المفتاحية في Ruby مع القيم الافتراضية كافية. يصبح استخدام المُنشئ مفيدًا عندما يمكن تكرار الأجزاء، أو عندما يكون الترتيب مهمًا، أو عندما يحتاج التركيب إلى التحقق منه قبل إنشاء الكائن:
Pizza.new(size: "large", crust: "thin") # خيارات قليلة: كلمات مفتاحية
Query.new.from("users").where("age > 18").where("active = 1").limit(10).to_sالتحدي
سهلأكمل PizzaBuilder وPizza. تُعيد خطوات المنشئ size(value) وcrust(value) وtopping(name) (القابلة للتكرار) المنشئ. تُطلق build الخطأ ArgumentError مع size is required عند عدم تقديم حجم، وتستخدم القشرة classic عند عدم اختيار أي قشرة، وتُعيد كائنًا من نوع Pizza. تُعيد Pizza#to_s القيمة large thin pizza with cheese, ham أو small classic pizza with no toppings.
كل سطر إدخال هو طلب واحد مثل size=large crust=thin topping=cheese topping=ham. يرسل الكود المزوَّد كل جزء إلى المنشئ بالترتيب، من خلال التسلسل، ويطبع البيتزا أو رسالة الخطأ.
ضع كودك في pizza.rb وpizza_builder.rb. يحتوي main.rb على كود الإدخال/الإخراج المزوَّد، ولا يمكن تعديله.
جرّب بنفسك
require_relative 'pizza'
require_relative 'pizza_builder'
# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
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
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتمتغيرات النسخةالأساليب و selfto_s و inspectمراجعة - بطاقة المكتبة7تعدد الأشكال والكتابة بأسلوب البطة
تعدد الأشكالالكتابة بأسلوب البطةالأساليب المجردةالحالات والفئاتمراجعة - طرق الدفع3أساليب ومتغيرات الأصناف
أساليب الأصنافمتغيرات كائنات الأصنافالثوابتأساليب الإنشاءمراجعة - رموز القسائمتدرّب بنفسك: مترجم Ruby عبر الإنترنت