يهدف نمط التصميم معمل التجريد Abstract Factory إلى توفير واجهة Interface لإنشاء مجموعة من الكائنات المرتبطة أو المنفصلة دون الحاجة إلى التعامل مع أصنافها الفعليّة. كما يوفّر هرمية Hierarchy تغلّف الكثير من المنصات Platforms المحتملة، وتعمل على بناء مجموعة من “المنتجات”.
ينطلق نمط التصميم هذا من مبدأ أن العامل new
مؤذٍ وينبغي التقليل من استخدامه.
ملاحظة: نعني بالتغليف Encapsulation في إطار البرمجة كائنيّة التوجه Object-oriented programming تلك الآليّة التي تتيح جمع البيانات (الخاصيّات Attributes) والإجراءات المطبّقة عليها (التوابع Methods) ضمن نفس الكائن، مع تقييد إمكانيّة وصول الكائنات الأخرى إلى عناصر الكائن.
المشكلة
إذا توجب على التطبيق Application أن يكون محمولا Portable، فلا بد من تغليف اعتمادات المنصات Platform dependencies التي يُراد له أن يعمل عليها. قد تتضمن هذه الاعتمادات نظام النوافذ، نظام التشغيل، قاعدة البيانات وغيرها. في كثير من الأحيان لا يُصمَّم التغليف مسبقا لأخذ الاعتمادات بالحسبان، فتبدأ عبارات الاختبار (if.. else
) مع خيارات لجميع المنصات الحالية المدعومة، بالتكاثر كالأرانب داخل الشفرة البرمجية.
المناقشة
يوفّر نمط التصميم معمل التجريد Abstract Factory مستوى من المراوغة يجرّد Abstract عمليّة إنشاء أصناف من الكائنات، المرتبطة أو المنفصلة؛ وبالتالي لا يحدّد طريقة التنفيذ الفعليّة للأصناف محلّ التساؤل.
المعمل؛ أي كائن من صنف Factory
؛ هو - حسب هذا النمط - خادم يوفّر خدمات إنشاء الأصناف التي نريد تجريدها - اعتمادات المنصات مثلا - لبقيّة الكائنات التي تلعب دور العميل. لا يمكن للعملاء بأي حال من اﻷحوال إنشاء الأصناف المقصودة بأنفسهم، بل يطلبون من المعمل فعل ذلك، عن طريق توابع مناسبة.
تسهّل هذه الآلية تبديل مجموعات المنتجات، لأن الصنف المحدد في كائن المعمل يظهر مرة واحدة فقط في التطبيق، وذلك في المكان الذي استهل Instantiated فيه. يمكن للتطبيق ببساطة أن يبادل بين مجموعة كاملة من المنتجات عن طريق استهلال صنف فعليّ آخر من المعمل. وبما أن الخدمة التي يقدمها كائن المعمل واسعة الانتشار، فإنها تُنفَّذ عادة باستخدام النمط المفرد The Singleton pattern.
ملاحظة: يحيل مفهوم التجريد Abstraction في هندسة البرمجيّات إلى الآليّة التي يُتخلَّص بموجبها من تعقيدات نظام مّا بتحديد مستوى من التعقيد لا يتجاوزه من يتفاعل مع النظام، ممّا يعني أنه يحذف التفاصيل الأكثر تعقيدا. يعتمد التجريد على استخلاص العناصر الرئيسية المطلوبة لحل المُشكلة والتركيز على هذه العناصر فقط وإهمال كافة التفاصيل الأخرى.
الهيكلية
يعرّف معمل التجريد تابعا Method لكل صنف منتَج. يغلّف كل تابع العامل new
والصنف الفعلي المحدد للمنصّة؛ ثم بعد ذلك، تتم نمذجة كل “منصة” بصنف مشتق Derived class من المعمل.
مثال
إن الهدف من نموذج معمل التجريد هو توفير واجهة لإنشاء مجموعات من الكائنات المرتبطة دون تحديد أصنافها الفعلية. يوجد مثال على هذا النمط في طبع الصفائح المعدنية المستخدمة في صناعة المركبات اليابانية. تعدّ معدات الطبع هذه معمل تجريد، حيث تنشئ أجزاء المركبة الآلية. تُستخدم الآلة نفسها في طبع الأبواب اليمنى واليسرى، المصدات الأمامية اليمنى، اليسرى وغطاء المحرك وغيرها، وذلك من أجل نماذج مختلفة من السيارات. تُستخدم آلات نقل (التوابع) في تغيير قوالب الطبع وإنتاج نوعيّة جديدة من المعدّات (أصناف فعلية).
يوفّر معمل التجريد StampingEquipment
في مخطَّط الأصناف التالي تابعًا stampPart
لكلّ مجموعة منتجات (stampWheel
مثلا للعجلات Wheels وstampDoor
للأبواب Doors). تستدعي الكائنات العميلة Clients (بقيّة أجزاء التطبيق) التابع المناسب لمجموعة المنتجات التي تريدها، مع تحديد نوعيّة (صنف) النموذج الذي تريد إنشاء كائن منه. يتضمّن التابع stampPart
العامل new
الذي ينشئ نموذجا جديدا باستدعاء الصنف الفعلي من بين مجموعات الأصناف ModelXHood
، ModelXWheels
وModelXDoor
(حيث X
عدد يمثل معرّف نموذج من المنتجات). نحصُل من العملية السابقة على كائن من معمل التجريد StampingEquipment
لكنّه يحمل خواصّ المنتج الذي نريده، ولا يتبقّى لنا للحصول على المنتج سوى استدعاء التابع المناسب: stampHood
، stampWheel
أو stampDoor
.
إن استدعينا مثلا التابع اstampWhee
في معمل التجريد StampingEquipment
مع تحديد الصنف Model1Wheels
(النموذج رقم 1 من العجلات) فسنحصُل على كائن من الصنف StampingEquipment
لديه تابع stampWheel
يؤدّي استدعاءه إلى الحصول على كائن من الصنف Model1Wheels
. إن أردنا الآن عجلات من النموذج رقم 2
فكلّ ما علينا فعله هو اتباع نفس الطريقة ولكن مع تحديد Model2Wheels
بدلا من Model1Wheels
عند استدعاء اstampWhee
في معمل التجريد.
نفس الشيء ينطبق على الكائنات الأخرى، مع تغيير اسم التابع في معمل التجريد حسب مجموعة الأصناف (stampHood
بالنسبة لنماذج اﻷغطية ModelXHood
، وstampDoor
بالنسبة لنماذج الأبواب ModelXDoor
).
لاحظ أنه بهذه الطريقة لن نحتاج لاستهلال الصنف StampingEquipment
(إنشاء كائن منه) سوى مرة واحدة، ثم نستدعي بعدها التوابع المناسبة لنوعيّة المنتجات التي نريد. أي أن العميل هنا يعمل في مستوى من التعقيد أقلّ بكثير ممّا كان سيعمل عليه لو أنه تولّى بنفسه استهلال الأصناف الفعليّة (ModelXHood
، ModelXWheels
وModelXDoor
) وما قد يترتّب عن ذلك من تعريف للخاصيّات والتوابع وكيفية عملها وغيرها من التفاصيل.
قائمة التدقيق
ينبغي - قبل اللجوء إلى نمط التصميم معمل التجريد التأكّد من حاجتك إليه عمليًّا وذلك بـ:
- تقرير ما إذا كانت اعتمادات المنصة وخدمات الإنشاء هي المصدر الحالي للمشكلة.
- إعداد مصفوفة “منصات” مقابل “منتجات”.
تأكّد عند استخدام هذا النمط من:
- تعريف واجهة للمعمل تتكّون من تابع معمل لكل “منتج”.
-
تعريف صنف مشتق من المعمل لكل منصة لتغليف كافة استدعاءات العامل
new
. -
حذف جميع استدعاءات العامل
new
من الصنف العميل وجعله يستخدم توابع المعمل في إنشاء الكائنات للمنتَج.
ترجمة - بتصرّف - للمقال Abstract Factory Design Pattern لأصحابه Alexander Shvets, Gerhard Frey, Marina Pavlova.
حقوق الصورة البارزة محفوظة لـ Freepik
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.