المحتوى:

  1. أنماط التصميم الإبداعية “Creational design patterns “
  2. ما هو نمط التصميم الإبداعي” prototype design pattern”
  3. مشكلة يمكن حلها باستخدام نمط التصميم” prototype design pattern”
  4. حل المشكلة باستخدام نمط التصميم” prototype design pattern”
  5. بناء نمط التصميم الإبداعي” prototype design pattern”
  6. تمثيل نمط التصميم ” prototype design pattern” بشكل كود
  7. قابلية نمط التصميم ” prototype design pattern” للتطبيق
  8. كيفية تنفيذ نمط التصميم ” prototype design pattern”
  9. إيجابيات وسلبيات نمط التصميم ” prototype design pattern “
  10. علاقات نمط التصميم ” prototype design pattern ” مع الأنماط الأخرى
  11. الخاتمة
  12. المراجع

    1.أنماط التصميم الإبداعية “Creational patterns“:
    تحدثنا في المقالة السابقة عن أنماط التصميم الإبداعي التي كانت تلخص عملية إنشاء مثيل (instantiation process). وكيف أنها تساعد في جعل النظام مستقلاً عن كيفية إنشاء كائناته وتكوينها وتمثيلها. يستخدم نمط إنشاء الفئة الوراثة لتغيير الفئة التي تم إنشاء مثيل لها، في حين أن نمط إنشاء الكائن سوف يقوم بتفويض إنشاء مثيل إلى كائن آخر.
    تصبح الأنماط الإبداعية مهمة مع تطور الأنظمة لتعتمد بشكل أكبر على تكوين الكائن بدلاً من وراثة الفئة. وعندما يحدث ذلك، يتحول التركيز بعيدًا عن الترميز الثابت لمجموعة ثابتة من السلوكيات نحو تحديد مجموعة أصغر من السلوكيات الأساسية التي يمكن تجميعها في أي عدد من السلوكيات الأكثر تعقيدًا. وبالتالي فإن إنشاء كائنات ذات سلوكيات معينة يتطلب أكثر من مجرد إنشاء مثيل لها.
    توفر أنماط التصميم الإبداعي آليات مختلفة لإنشاء الكائنات، مما يزيد من المرونة وإعادة
    استخدام التعليمات البرمجية الموجودة.

وقد تحدثنا في المقالة السابقة عن ثالث نمط تصميم إبداعي وهو ” Builder pattern
هو نمط تصميم إبداعي يتيح لنا إنشاء كائنات معقدة خطوة بخطوة. ويتيح لنا النمط إنتاج أنواع وتمثيلات مختلفة لكائن ما باستخدام نفس كود البناء. وسنكمل بالتحدث عن تتمة أنواع التصميم الإبداعي وسنبدأ بال ” prototype pattern”

  1. ما هو نمط التصميم الإبداعي” prototype pattern”
    النموذج الأولي هو نمط تصميم إبداعي يتيح لنا نسخ الكائنات الموجودة دون جعل التعليمات البرمجية الخاصة بنا تعتمد على فئاتها.
    نمط التصميم “النموذجي” أو Prototype Design Pattern هو أحد الأنماط المستخدمة في برمجة الحاسوب والبرمجة الشيئية. يندرج هذا النمط تحت تصنيف أنماط التصميم الخمسة والعشرين المعروفة. يُستخدم هذا النمط لإنشاء كائنات جديدة بواسطة استخدام نسخة من كائن موجود بالفعل. يستخدم هذا النمط عادةً عندما يكون إنشاء الكائنات الجديدة مكلفًا من حيث الوقت أو الموارد، لذلك يتم إنشاء نموذج أولي (Prototype) ويتم استخدامه لإنشاء الكائنات الجديدة من خلال نسخه.

في هذا النمط، يحتوي النموذج (Prototype) على واجهة (Interface) تعرف عملية النسخ، ويحتوي الكائنات التي تستخدم النموذج على طريقة للحصول على نسخة من النموذج وتقوم بتطبيق عملية النسخ عليها.

هذا النمط يسمح بتقليل الاعتماد على توليد الكائنات مباشرة، مما يقلل من العبء على موارد النظام، ويزيد من قابلية إعادة الاستخدام وصيانة الكود.

  1. مشكلة يمكن حلها باستخدام نمط التصميم” prototype pattern”
    لنفترض أن لدينا كائنًا، ونريد إنشاء نسخة طبق الأصل منه. كيف يمكننا أن نفعل ذلك؟ أولاً، علينا إنشاء كائن جديد من نفس الفئة. ثم يتعين علينا استعراض كافة حقول الكائن الأصلي ونسخ قيمها إلى الكائن الجديد.

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

  1. حل المشكلة باستخدام نمط التصميم” prototype pattern”
    يقوم نمط النموذج الأولي بتفويض عملية الاستنساخ إلى الكائنات الفعلية التي يتم استنساخها. يعلن النمط عن واجهة مشتركة لجميع الكائنات التي تدعم الاستنساخ. تتيح لنا هذه الواجهة استنساخ كائن دون ربط التعليمات البرمجية الخاصة بنا بفئة ذلك الكائن. عادةً ما تحتوي هذه الواجهة على طريقة استنساخ واحدة فقط.
    إن تنفيذ طريقة الاستنساخ متشابه جدًا في جميع الفئات. تقوم الطريقة بإنشاء كائن من الفئة الحالية وتنقل جميع قيم الحقول الخاصة بالكائن القديم إلى القيمة الجديدة. يمكنك أيضًا نسخ الحقول الخاصة لأن معظم لغات البرمجة تسمح للكائنات بالوصول إلى الحقول الخاصة للكائنات الأخرى التي تنتمي إلى نفس الفئة.
    يسمى الكائن الذي يدعم الاستنساخ بالنموذج الأولي. عندما تحتوي كائناتنا على عشرات الحقول ومئات التكوينات المحتملة، فقد يكون استنساخها بمثابة بديل للفئة الفرعية.
    وسنرى كيفية العمل: يمكننا إنشاء مجموعة من الكائنات، التي تم تكوينها بطرق مختلفة. عندما نحتاج إلى كائن مثل ذلك الذي قمنا بتكوينه، ما علينا سوى استنساخ نموذج أولي بدلاً من إنشاء كائن جديد من البداية.

5.بناء نمط التصميم الإبداعي”prototype pattern”

    • تعلن واجهة النموذج الأولي عن طرق الاستنساخ. في معظم الحالات، تكون هذه طريقة استنساخ واحدة.
    • تطبق فئة النموذج الأولي الخرساني طريقة الاستنساخ. بالإضافة إلى نسخ بيانات الكائن الأصلي إلى النسخة المستنسخة، قد تتعامل هذه الطريقة أيضًا مع بعض حالات الحافة لعملية الاستنساخ المتعلقة باستنساخ الكائنات المرتبطة، وفك التبعيات العودية، وما إلى ذلك.
    • يمكن للعميل إنتاج نسخة من أي كائن يتبع واجهة النموذج الأولي.
    1. تمثيل نمط التصميم ” prototype pattern” بشكل كود

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

    7.قابلية نمط التصميم “prototype pattern” للتطبيق

      • استخدم نمط النموذج الأولي عندما لا يعتمد الكود الخاص بنا على فئات محددة من الكائنات التي تحتاج إلى نسخها.
        يحدث هذا كثيرًا عندما تعمل التعليمات البرمجية الخاصة بنا مع الكائنات التي تم تمريرها إلينا من تعليمات برمجية تابعة لجهة خارجية عبر بعض الواجهات. الفئات الملموسة لهذه الكائنات غير معروفة، ولا يمكننا الاعتماد عليها حتى لو أردنا ذلك.

      يوفر نمط النموذج الأولي لرمز العميل واجهة عامة للعمل مع كافة الكائنات التي تدعم الاستنساخ. تجعل هذه الواجهة رمز العميل مستقلاً عن الفئات المحددة للكائنات التي يستنسخها.

      • استخدم هذا النمط عندما نريد تقليل عدد الفئات الفرعية التي تختلف فقط في طريقة تهيئة الكائنات الخاصة بها.
        لنفترض أن لدينا فئة معقدة تتطلب تكوينًا شاقًا قبل استخدامها. هناك عدة طرق شائعة لتكوين هذه الفئة، وهذا الرمز منتشر عبر تطبيقنا لتقليل التكرار، يمكننا إنشاء عدة فئات فرعية ووضع كل كود التكوين الشائع في مُنشئاتها. لقد قمنا بحل مشكلة التكرار، ولكن لدينا الآن الكثير من الفئات الفرعية الوهمية.

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

      1. كيفية تنفيذ نمط التصميم”prototype pattern”
      • نقوم بإنشاء واجهة النموذج الأولي وإعلان طريقة الاستنساخ فيها. أو نقوم فقط بإضافة الطريقة إلى جميع فئات التسلسل الهرمي للفئات الموجودة، إذا كان لدينا واحدة.
      • يجب أن نحدد فئة النموذج الأولي المُنشئ البديل الذي يقبل كائنًا من تلك الفئة كوسيطة ويجب على المنشئ نسخ قيم كافة الحقول المحددة في الفئة من الكائن الذي تم تمريره إلى المثيل الذي تم إنشاؤه حديثًا. إذا كنا نقوم بتغيير فئة فرعية، فيجب علينا استدعاء المُنشئ الأصلي للسماح للفئة الفائقة بمعالجة استنساخ حقولها الخاصة.

      إذا كانت لغة البرمجة الخاصة بنا لا تدعم التحميل الزائد للطريقة، فلن نتمكن من إنشاء “نموذج أولي” منفصل. وبالتالي، يجب إجراء نسخ بيانات الكائن إلى النسخة التي تم إنشاؤها حديثًا ضمن طريقة النسخ. ومع ذلك، فإن وجود هذا الرمز في مُنشئ عادي يعد أكثر أمانًا لأنه يتم إرجاع الكائن الناتج كامل التكوين مباشرة بعد استدعاء عامل التشغيل الجديد.

      • تتكون طريقة الاستنساخ عادةً من سطر واحد فقط: تشغيل مشغل جديد باستخدام الإصدار النموذجي للمنشئ. ونلاحظ أن كل فئة يجب أن تتجاوز بشكل صريح طريقة الاستنساخ وتستخدم اسم الفئة الخاص بها مع عامل التشغيل الجديد. وإلا فإن طريقة الاستنساخ قد تنتج كائنًا من الفئة الأصلية.
      • اختياريًا، نقوم بإنشاء سجل نموذج أولي مركزي لتخزين كتالوج النماذج الأولية المستخدمة بشكل متكرر.
      • يمكننا تنفيذ السجل كفئة مصنع جديدة أو وضعه في فئة النموذج الأولي الأساسي باستخدام طريقة ثابتة لجلب النموذج الأولي. يجب أن نبحث هذه الطريقة عن نموذج أولي بناءً على معايير البحث التي يمررها رمز العميل إلى الطريقة. قد تكون المعايير إما علامة سلسلة بسيطة أو مجموعة معقدة من معلمات البحث. بعد العثور على النموذج الأولي المناسب، يجب على السجل استنساخه وإعادة النسخة إلى العميل.
      • أخيرًا، سنستبدل الاستدعاءات المباشرة لمنشئي الفئات الفرعية باستدعاءات طريقة المصنع لسجل النموذج الأولي.
      1. إيجابيات وسلبيات نمط التصميم “prototype pattern”
        الإيجابيات:
      • يمكننا استنساخ الكائنات دون الاقتران بفئاتها المحددة.
      • يمكننا التخلص من رمز التهيئة المتكرر لصالح استنساخ النماذج الأولية المعدة مسبقًا.
      • يمكننا إنتاج كائنات معقدة بشكل أكثر سهولة.
      • يمكننا الحصول على بديل للوراثة عند التعامل مع إعدادات التكوين المسبقة للكائنات المعقدة.

      السلبيات:

      • قد يكون استنساخ الكائنات المعقدة التي لها مراجع دائرية أمرًا صعبًا للغاية.
      1. علاقات نمط التصميم “prototype pattern”مع الأنماط الأخرى
      • تبدأ العديد من التصميمات باستخدام أسلوب المصنع (أقل تعقيدًا وأكثر قابلية للتخصيص عبر الفئات الفرعية) وتتطور نحو Abstract Factory أو Prototype أو Builder (أكثر مرونة، ولكن أكثر تعقيدًا).
      • تعتمد فئات Abstract Factory غالبًا على مجموعة من أساليب المصنع، ولكن يمكننا أيضًا استخدام النموذج الأولي لتكوين الأساليب في هذه الفئات.
      • يمكن أن يساعدنا النموذج الأولي عندما نحتاج إلى حفظ نسخ من الأوامر في السجل.
      • غالبًا ما تستفيد التصميمات التي تستخدم Composite وDecorator من استخدام النموذج الأولي حيث يتيح لنا تطبيق النمط استنساخ الهياكل المعقدة بدلاً من إعادة بنائها من الصفر
      • النموذج الأولي لا يعتمد على الميراث، لذلك ليس له عيوبه من ناحية أخرى، يتطلب النموذج الأولي تهيئة معقدة للكائن المستنسخ. تعتمد طريقة المصنع على الوراثة ولكنها لا تتطلب خطوة تهيئة.
      • في بعض الأحيان يمكن أن يكون النموذج الأولي بديلاً أبسط لـ Memento. ينجح هذا إذا كان الكائن، وحالته التي نريد تخزينها في السجل، واضحة إلى حد ما ولا تحتوي على روابط لموارد خارجية، أو إذا كان من السهل إعادة إنشاء الروابط.
      • يمكن تنفيذ كل من المصانع المجردة والبنائين والنماذج الأولية (Abstract Factories, Builders and Prototypes) كوحدات فردية
      1. الخاتمة

      في الختام، يعد نمط النموذج الأولي نمطًا تصميميًا قويًا يعزز المرونة والكفاءة والبساطة في إنشاء الكائنات. من خلال السماح باستنساخ الكائنات بدلاً من إنشاء مثيل لها مباشرةً، فإنه يوفر طريقة نظيفة وفعالة لإدارة التسلسلات الهرمية المعقدة للكائنات مع تقليل الاعتماد على التطبيقات الملموسة. حيث يوفر نمط النموذج الأولي العديد من المزايا، بما في ذلك:
      المرونة: تسمح بإنشاء كائنات جديدة عن طريق نسخ الكائنات الموجودة، مما يوفر المرونة في إنشاء الكائنات دون ربط رمز العميل بفئات محددة.

      الكفاءة: بما أنه يتم استنساخ الكائنات بدلاً من إنشائها من الصفر، فإن نمط النموذج الأولي يمكن أن يحسن الأداء بشكل كبير، خاصة عند إنشاء كائنات معقدة.

      البساطة: تعمل على تبسيط إنشاء كائنات جديدة عن طريق تجريد عملية الاستنساخ، مما يسهل إدارة التسلسل الهرمي للكائنات والحفاظ عليه.

      ومع ذلك، من الضروري مراعاة العيوب المحتملة، مثل إدارة حالة الكائنات المستنسخة والتأكد من أن عملية الاستنساخ تكرر حالة الكائن الأصلي بدقة.

      بشكل عام، يعد نمط النموذج الأولي أداة قيمة في ترسانة المطورين، خاصة في السيناريوهات التي يكون فيها إنشاء الكائن معقدًا أو يكون الأداء مصدر قلق. من خلال الاستفادة من نمط النموذج الأولي، يمكن للمطورين تصميم أنظمة أكثر قوة وكفاءة مع تعزيز إمكانية إعادة استخدام التعليمات البرمجية وقابلية الصيانة.

      1. المراجع

      https://refactoring.guru/design-patterns/prototype

      https://www.geeksforgeeks.org/prototype-design-pattern

      Facebook
      Twitter
      YouTube
      LinkedIn