نمط 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، التي تُرجع to_s الخاصة بها square 3: area 9.00، مع كتابة اسم الفئة بأحرف صغيرة، والحجم والمساحة بمنزلتين عشريتين. استخدم 3.14159 لقيمة pi وMath.sqrt(3) / 4 * size**2 للمثلث. يبحث المصنع عن النوع في ثابت تجزئة مجمّد KINDS ويُرجع nil لنوع غير معروف.
يقرأ الكود الم provided الأسطر square 3، ويطلب من المصنع إنشاء كل شكل ويطبعه، أو يطبع unknown shape: hexagon.
ضع الكود الخاص بك في shape.rb وsquare.rb وcircle.rb وtriangle.rb وshape_factory.rb. يحتوي main.rb على كود الإدخال/الإخراج الم provided، ولا يمكن تعديله.
جرّب بنفسك
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 عبر الإنترنت