نمط Factory
جزء من قسم البرمجة كائنية التوجه في رحلة Ruby على Coddy. الدرس 43 من 57.
يضع نمط المصنع إنشاء الكائنات في مكان واحد. يطلب المستدعون ما يحتاجون إليه، غالبًا بالاسم، ويحصلون على كائن جاهز دون معرفة الفئة التي أُنشئ منها:
class Square
def initialize(side)
@side = side
end
def area
@side * @side
end
end
class Circle
def initialize(r)
@r = r
end
def area
(3.14159 * @r * @r).round(2)
end
end
class ShapeFactory
def self.create(kind, size)
case kind
when "square" then Square.new(size)
when "circle" then Circle.new(size)
end
end
end
puts ShapeFactory.create("square", 3).area
puts ShapeFactory.create("hexagon", 3).inspectالناتج:
9
nilتجعل خريطة من الأسماء إلى الأصناف المصنع أقصر وأسهل في التوسعة. الأصناف كائنات، لذا يمكن تخزينها في خريطة وإرسال new إليها:
class Dog
def speak
"Woof"
end
end
class Cat
def speak
"Meow"
end
end
class AnimalFactory
KINDS = { "dog" => Dog, "cat" => Cat }.freeze
def self.create(kind)
klass = KINDS.fetch(kind) { raise ArgumentError, "unknown animal: #{kind}" }
klass.new
end
end
puts AnimalFactory.create("cat").speak
begin
AnimalFactory.create("cow")
rescue ArgumentError => e
puts e.message
endالمخرجات:
Meow
unknown animal: cowيمكن للمصنع أيضًا أن يتيح لشفرة أخرى تسجيل أنواع جديدة أثناء التشغيل، لذا فإن إضافة نوع لا تعني تعديل المصنع:
class Plugins
@kinds = {}
class << self
def register(name, klass)
@kinds[name] = klass
end
def build(name)
@kinds.fetch(name).new
end
def names
@kinds.keys.sort
end
end
end
class Zip
def run
"zipping"
end
end
Plugins.register("zip", Zip)
puts Plugins.build("zip").run
p Plugins.namesالناتج:
zipping
["zip"]لا تعتمد الجهات المستدعية إلا على ما يمكن للكائنات فعله، مثل area أو speak، وليس على الأصناف الملموسة مطلقًا. يعني الشكل الجديد إضافة صنف واحد وإدخال جديد في المصنع، دون أي تغيير في أي موضع آخر:
shape = ShapeFactory.create(kind, size) # Square, Circle, ...
puts shape.area # الجهة المستدعية لا تذكر اسم أي صنف مطلقًاالتحدي
سهلأكمل الأشكال وShapeFactory.create(kind, size). تشترك Square وCircle وTriangle (متساوي الأضلاع) في الفئة الأساسية Shape، التي تُرجع square 3: area 9.00 من to_s، مع اسم الفئة بحروف صغيرة والحجم والمساحة بمنزلتين عشريتين. استخدم 3.14159 لقيمة pi وMath.sqrt(3) / 4 * size**2 للمثلث. يبحث المصنع عن النوع في ثابت تجزئة مجمّد KINDS، ويُرجع nil إذا كان النوع غير معروف.
يقرأ الكود الموفّر أسطرًا مثل square 3، ويطلب من المصنع إنشاء كل شكل ويطبعه، أو unknown shape: hexagon.
ضع كودك في shape.rb وsquare.rb وcircle.rb وtriangle.rb وshape_factory.rb. يحتوي main.rb على كود الإدخال/الإخراج الموفّر، ولا يمكن تعديله.
جرّب بنفسك
require_relative 'shape'
require_relative 'square'
require_relative 'circle'
require_relative 'triangle'
require_relative 'shape_factory'
# شيفرة الإدخال والإخراج المقدَّمة: اتركها كما هي
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
kind, size = line.split
shape = ShapeFactory.create(kind, size.to_f)
puts shape || "unknown shape: #{kind}"
end
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتمتغيرات النسخةالأساليب و selfto_s و inspectمراجعة - بطاقة المكتبة7تعدد الأشكال والكتابة بأسلوب البطة
تعدد الأشكالالكتابة بأسلوب البطةالأساليب المجردةالحالات والفئاتمراجعة - طرق الدفع3أساليب ومتغيرات الأصناف
أساليب الأصنافمتغيرات كائنات الأصنافالثوابتأساليب الإنشاءمراجعة - رموز القسائمتدرّب بنفسك: مترجم Ruby عبر الإنترنت