المعلوماتية > برمجيات

أنماط التصميم Design Patterns الأنماط الإنشائية (Creational Patterns)

تخيّل أنّ هناك مطعمًا جديدًا يُنشَأ ويريد تقديم خدمة توصيل الطعام إلى المنازل، ولكن يريد التخطيط لإزالة عبء التوصيل عن عاتقه، ولذلك؛ يتعاقد مع شركة مُخصصة لتوصيل الطلبات.

لا يريد المطعم أن يحصر الشركة المُتَعاقد معها بوسيلة نقل معينة؛ إذ تستطيع الشركة استخدام أية وسيلة نقل متوفرة لنقل الطلبيات؛ مثل سيارة، أو دراجة هوائية، أو دراجة كهربائية، أو أية وسيلة تريد توفيرها في المستقبل، فيستخدم المطعم إحدى أفكار أنماط التصميم الإنشائية لحل هذه المعضلة.

هناك العديد من أنماط التصميم الإنشائية المِعيارية، سنتحدث عن الثلاثة الآتية منها: 

نمط مصنع الأغراض المُجرّد Abstract Factory pattern.

نمط البنّاء Builder pattern.

نمط الإفرَاد (Singleton pattern (1.

نمط مصنع الأغراض (Abstract Factory Pattern)

هدفه تزويد مُستخدمه بواجهة برمجية interface بهدف إنشاء مجموعة من الأغراض المُعتمدة بعضها على بعض بدون تحديد كيفية تنجيز الأصناف المُشتقة Concrete classes (1).

مثلًا، بالعودة إلى مثال المطعم وشركة التوصيل؛ تُزوّد شركة التوصيل المطعم بصنف عام (abstract type) يُدعَى "مصنع طُرق النقل TransportationFactory"، يحتوي هذا الصنف على العمليات الأساسية التي يستطيع المطعم طلبها من شركة التوصيل؛ مثل إنشاء طلب توصيل جديد (CreateDelievery).

الآن، ليستفيد المطعم من شركة التوصيل ويتخلص من عبء اختيار طريقة التوصيل؛ فهو يجبر شركة التوصيل عند التواصل مع المطعم وأخذ الطلب منه أن تُزوّده بصنف مُشتق (Concrete class) من مَصنع طُرق النقل (TransportationFactory) يحدد بواسطته طريقة النقل. فما على المطعم إلا استدعاء عملية CreateDelivery لكي تُنهي الطلب، فيقع على شركة التوصيل عاتق إنشاء طلب التوصيل وتحديد طريقة النقل على نحو تفصيلي.

متى نستخدم هذا النمط؟ 

- عندما لا يستطيع الصنف (المطعم في مثالنا) تحديدَ أي نوع مُحدد من الأغراض سيُنشَأ (طريقة النقل في مثالنا).

- عندما يستخدم الصنف (المطعم) أصنافًا فرعية sub-classes (مصنع طُرق النقل) لتحديد أي صنف من الأغراض سيُنشَأ (2).

نمط الإفرَاد (Singleton Pattern)

على الرغم من أنّ نمط الإفراد يقع ضمن تصنيف الأنماط الإنشائية؛ لكنه يَحدّ من إنشاء الأغراض عوضًا عن المساعدة على إنشائها (2).

إذ يُرغم هذا النمط النظامَ على إنشاء غرض واحد -وواحد فقط في فترة حياة النظام- ويوفّر نقطة وصول واحدة لهذا الغرض ليستخدمه أيُّ جزء من أجزاء النظام. 

على سبيل المثال، بالعودة إلى مثال المطعم وشركة التوصيل؛ يرغب المطعم في التعامل مع شركة واحدة فقط لتوصيل الطلبيات، ولا يرغب أبدًا تغيير هذه الشركة في فترة عمل المطعم، ولا يستطيع تغييرها إلا بإغلاق المطعم وإعادة فتحه. هنا تُعدّ شركة التوصيل من نوع singleton؛ إذ يتوفر غرض واحد فقط يستخدمه موظفو المطعم جميعهم.

وتكون مسؤولية الحفاظ على أن يتعامل المطعم مع شركة واحدة فقط على عاتق شركة التوصيل نفسها (3).

متى نستخدم هذا النمط ؟

- عندما يكون هناك الحاجة إلى غرض واحد وواحد فقط من صنف ما، وهناك طريقة مُحددة للوصول إلى هذا الغرض (شركة التوصيل).

- عند إتاحة إمكانية توسيع التنجيز (implementation) عن طريق اشتقاق الصنف sub-classing، ويستطيع مستخدمو هذا الصنف (المطعم) استخدام التنجيز الجديد بدون التعديل على البنية الداخلية الخاص بهم (3). 

نمط البنّاء (Builder Pattern) 

يُشبه نمط "مصنع الأغراض" ولكن يُعطي تحكمًا أكبر في كيفية إنشاء الغرض؛ إذ تستطيع بناء أجزاء الغرض المُعقّد (Complex object) على نحو تسلسلي.

يتألف نمط البنّاء من 4 مكونات أساسية:

في مثال المطعم السابق؛ البنّاء العام هو TransportationBuilder، وهو صنف مُجرّد يعرّف العمليات اللازمة لبناء وسيلة نقل. نُعرّف عدة بنّائين مُخصصين مثل BicycleTransportationBuilder و CarTransportationBuilder، فتُنجَز الخطوات اللازمة لكل من وسيلة النقل بالدراجة وبالسيارة على التوالي.

بعد ذلك، يستخدم المطعم (وهو المُخرِج) البنّاء العام ويترك تحديد البنّاء المُخصص لشركة التوصيل للحصول على غرض وسيلة النقل المُلائمة (وهو المنتج).

متى نستخدم هذا النمط؟

- عندما تكون خوارزمية بناء الغرض مُعقدة، يمكن تجزئتها إلى أجزاء مُنفصلة عن الغرض وتجميعها.

- عندما تكون عملية بناء الغرض تسمح بعدة تمثيلات مختلفة من أجزاء الغرض الذي يُبنَى (3).

توفّر أنماط البناء الإنشائية عدة آليات لبناء الأغراض المُعقدة، وإنّ استخدامها في الأنظمة الكبيرة يسهّل عملية إعادة استخدام المكوّنات وجعل النظام أكثر مرونة، إضافةً إلى تسهيل اختبار النظام؛ فاختَر ما يلائم النظام الذي تبنيه.

المصادر

1- Spinellis D. Notable design patterns for domain-specific languages. Journal of Systems and Software [Internet]. 2001 [cited 22 April 2021];56(1):91-99. Available from: هنا

2- Gamma E, Helm R, Johnson R, Vlissides J. Design Patterns: Abstraction and Reuse of Object-Oriented Design. In: Nierstrasz O, ed. by. ECOOP’ 93 — Object-Oriented Programming. ECOOP 1993 Lecture Notes in Computer Science, vol 707 [Internet]. Berlin, Heidelberg: Springer; 1993 [cited 3 May 2021]. p. 406-431. Available from: هنا

3- Singleton [Internet]. Cs.unc.edu. [cited 22 November 2020]. Available from: هنا