نمط Factory
جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 55 من 61.
يركّز نمط المصنع عملية إنشاء الكائنات في دالة واحدة. وبدلًا من توزيع malloc وتعليمة التهيئة في أنحاء برنامجك، تستدعي دالة واحدة تقرّر ما الذي ستنشئه وتُرجع كائنًا جاهزًا للاستخدام.
يكون هذا النمط قويًا بشكل خاص عند دمجه مع تعدد الأشكال. يمكن لـ factory إرجاع أنواع ملموسة مختلفة من خلال مؤشر base مشترك، مع إخفاء تفاصيل الإنشاء عن المستدعي. يطلب المستدعي ببساطة "شكلاً"، وتقرر factory ما إذا كانت ستنشئ دائرة أو مستطيلاً أو شيئًا آخر.
إليك تطبيقًا نموذجيًا للمصنع:
typedef enum {
SHAPE_CIRCLE,
SHAPE_RECTANGLE
} ShapeType;
Shape* create_shape(ShapeType type) {
switch (type) {
case SHAPE_CIRCLE:
return (Shape*)create_circle(5.0);
case SHAPE_RECTANGLE:
return (Shape*)create_rectangle(4.0, 3.0);
default:
return NULL;
}
}يأخذ المصنع مُعرّفًا (عادةً ما يكون enum) ويستخدم عبارة switch لتحديد constructor الذي يجب استدعاؤه. ويُرجع Shape* بغضّ النظر عن النوع الفعلي الذي تم إنشاؤه. لا يحتاج المستدعي إلى معرفة شيء عن Circle أو Rectangle. فهو يعمل فقط مع النوع الأساسي:
Shape* s = create_shape(SHAPE_CIRCLE);
s->draw(s); // استدعاء متعدد الأشكال
free_shape(s);يجعل هذا النمط إضافة أنواع جديدة أمرًا سهلًا: ما عليك سوى إضافة قيمة enum جديدة وcase جديدة في factory. يظل باقي كودك دون تغيير.
التحدي
سهللنَبْنِ مصنع Pet: نظامًا ينشئ أنواعًا مختلفة من الحيوانات الأليفة من خلال function واحدة للمصنع. بدلًا من توزيع منطق الإنشاء في أنحاء الكود، ستجمعه في مكان واحد يقرر نوع الحيوان الأليف الذي يجب إنشاؤه بناءً على معرّف الإدخال.
ستنظّم الكود عبر ثلاثة ملفات:
pet.h: عرّف تعدادPetTypeبالقيمPET_DOGوPET_CATوPET_BIRD. أنشئ بنية أساسيةPetتحتوي على مؤشّر function لـspeak(يأخذconst Pet*ولا يُرجع شيئًا). صرّح عن function المصنعcreate_petالتي تأخذPetTypeوتُرجعPet*، بالإضافة إلى functionfree_petلتنفيذ التنظيف.pet.c: عرّف ثلاث بنيات ملموسة للحيوانات الأليفة، وهيDogوCatوBird، بحيث تدمج كل منهاPetباعتباره العضو الأول. نفّذ function لـلكل نوع: - تطبع الكلاب:
Woof! - تطبع القطط:
Meow! - تطبع الطيور:
Tweet!
المناسبة. ثم نفّذ مصنع create_pet: استخدم عبارة switch علىPetTypeلاستدعاء constructor الصحيح وإرجاع النتيجة على هيئةPet*. بالنسبة إلى الأنواع غير الصالحة، أرجِعNULL. نفّذfree_petلتحرير الذاكرة المخصّصة.- تطبع الكلاب:
main.c: اقرأ عددًا صحيحًا يمثّل نوع الحيوان الأليف (0 للكلب، و1 للقط، و2 للطائر). استخدم المصنع لإنشاء الحيوان الأليف المناسب، واستدعِ function الخاصة بـالخاصة به تعدديًا من خلال مؤشّر البنية الأساسية Pet*، ثم حرّر الحيوان الأليف.
سيستقبل برنامجك إدخالًا واحدًا: عددًا صحيحًا يحدد الحيوان الأليف المراد إنشاؤه.
ناتج المثال عندما يكون الإدخال 0:
Woof!ناتج المثال عندما يكون الإدخال 1:
Meow!ناتج المثال عندما يكون الإدخال 2:
Tweet!يكمن جمال نمط المصنع في أن main.c لا يحتاج إلى معرفة أي شيء عن بنيات Dog أو Cat أو Bird. فهو يعمل فقط مع النوع الأساسي Pet. تعني إضافة نوع جديد من الحيوانات الأليفة لاحقًا إضافة قيمة تعداد جديدة وحالة case جديدة في المصنع، من دون تغيير أي كود يستخدم الحيوانات الأليفة.
جرّب بنفسك
#include <stdio.h>
#include "pet.h"
int main(void) {
int type;
scanf("%d", &type);
// TODO: استخدم المصنع لإنشاء الحيوان الأليف المناسب
// Hint: حوّل الـ int إلى PetType
// TODO: استدعِ دالة speak بشكل متعدد الأشكال عبر مؤشر Pet*
// TODO: حرّر الحيوان الأليف
return 0;
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات البرمجة التركيبية
ملفات الترويسةحواجز التضمينملفات المصدرالدوال الساكنةمراجعة: آلة حاسبة تركيبية4التغليف (Encapsulation)
مفهوم الـ Opaque Pointersتعريف الـ Opaque Structsالـ Getters والـ Settersالتحقق من البيانات في الـ Settersملخص: الصندوق السري2الكائنات والأساليب
الـ Structs ككائناتمؤشر 'Self'صحة استخدام Constالمؤشر مقابل القيمةالأساليب المساعدةملخص: Point Manager5مشروع: حساب بنكي بسيط
إعداد المشروعتنفيذ الحساب3دورة حياة الكائن
نمط المنشئ (Constructor Pattern)نمط الهادم (Destructor Pattern)تهيئة الـ Stackالنسخ العميق (Deep Copy)مراجعة: String Wrapper6الوراثة عبر التركيب
تضمين الـ Structقاعدة العضو الأولالوصول إلى أعضاء الأبعملية الـ Upcastingمراجعة: هرمية الأشكال9مشروع: رسّام الأشكال
نظرة عامة على المشروعتنفيذ الدائرةتنفيذ المستطيلاستخدام تعدد الأشكالحاوية الأشكالتدرّب بنفسك: مترجم C عبر الإنترنت