المحتوى:

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

  1. أنماط التصميم الإنشائية”Structural patterns”

الأنماط الهيكلية هي فئة من أنماط التصميم في هندسة البرمجيات. تركِّز هذه الأنماط على تنظيم الفئات والكائنات المختلفة لتكوين هياكل أكبر وتوفير العلاقات فيما بينها وتهتم الأنماط الهيكلية في المقام الأول بتكوين الفئة وتكوين الكائن. نفكِّر في كيفية دمج الميراث المتعدد بين فئتين أو أكثر في فئة واحدة. والنتيجة هي فئة تجمع بين خصائص الفئات الأصلية وهناك موضوعان متكرران في هذا النمط:

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

لنأخذ على سبيل المثال، محررِّ رسم يتيح للمستخدمين رسم وترتيب العناصر الرسومية (الخطوط والمضلعات والنص وما إلى ذلك) في الصور والرسوم البيانية. التجريد الرئيسي لمحرر الرسم هو الكائن الرسومي، الذي له شكل قابل للتحرير ويمكنه رسم نفسه. حيث يتم تعريف واجهة الكائنات الرسومية بواسطة فئة مجرَّدة تسمى الشكل. يقوم المحرر بتعريف فئة فرعية من الشكل لكل نوع من الكائنات الرسومية: فئة Line Shape للخطوط، وفئة Polygon Shape للمضلعات، وما إلى ذلك.

  1. ما هو نمط التصميم الإنشائي “Bridge design pattern”

Bridge هو نمط تصميم هيكلي يسمح لنا بتقسيم فئة كبيرة أو مجموعة من الفئات ذات الصلة الوثيقة إلى تسلسلين هرميين منفصلين (التجريد والتنفيذ) ويمكن تطويرهما بشكل مستقل عن بعضهما البعض.
وقد تمَّ تصميمه لفصل التجريد عن تنفيذه بحيث يمكن أن يختلف الاثنان بشكل مستقل. وسنرى كيف يعمل:
التجريد: يمثِّل الواجهة عالية المستوى التي يستخدمها العملاء. ويحتوي عادةً على أساليب تقوم بتفويض العمل الفعلي إلى التنفيذ.

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

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

  1. مشكلة يمكن حلها باستخدام نمط التصميم”Bridge design pattern”

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

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

  1. حل المشكلة باستخدام نمط التصميم”Bridge design pattern”

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

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

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

التجريد والتنفيذ:

كتاب GoF (“Gang of Four” هو لقب يطلق على المؤلفين الأربعة للكتاب الأصلي حول أنماط التصميم، عناصر البرامج الموجهة للكائنات القابلة لإعادة الاستخدام https://refactoring.guru/gof-book.)

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

التجريد (وتسمى أيضاً الواجهة) هو طبقة تحكم عالية المستوى لبعض الكيانات. ليس من المفترض أن تقوم هذه الطبقة بأي عمل حقيقي بمفردها. يجب أن يفوض العمل إلى طبقة التنفيذ (وتسمى أيضاً النظام الأساسي).

لاحظ أنَّنا لا نتحدث عن واجهات أو فئات مجردة من لغة البرمجة الخاصة بنا. فهذه ليست نفس الأشياء. عند الحديث عن التطبيقات الحقيقية، ويمكن تمثيل التجريد من خلال واجهة المستخدم الرسومية (GUI)، ويمكن أن يكون التنفيذ هو رمز نظام التشغيل الأساسي (API) الذي تستدعيه طبقة واجهة المستخدم الرسومية استجابة لتفاعلات المستخدم.

بشكل عام، يمكننا توسيع هذا التطبيق في اتجاهين مستقلين:

  • يكون لدينا العديد من واجهات المستخدم الرسومية المختلفة (على سبيل المثال، مصممة للعملاء أو المسؤولين العاديين).
  • دعم العديد من واجهات برمجة التطبيقات المختلفة (على سبيل المثال، لنتمكن من تشغيل التطبيق ضمن أنظمة التشغيل Windows وLinux وmacOS).

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

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

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

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

  • نستخدم النمط عندما نحتاج إلى توسيع الفصل الدراسي في عدة أبعاد متعامدة (مستقلة).

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

  • نستخدم Bridge إذا كنت نريد أن نكون قادرين على تبديل التطبيقات في وقت التشغيل.

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

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

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

الإيجابيات:

  • يمكننا إنشاء فئات وتطبيقات مستقلة عن النظام الأساسي.
  • يعمل رمز العميل مع التجريدات عالية المستوى، أي لا يتعرض لتفاصيل المنصة.
  • مبدأ مفتوح/مغلق؛ يمكننا تقديم تجريدات وتطبيقات جديدة بشكل مستقل عن بعضها البعض.
  • مبدأ المسؤولية الفردية؛ يمكننا التركيز على المنطق عالي المستوى في التجريد وعلى تفاصيل النظام الأساسي في التنفيذ.

السلبيات:

  • تصبح التعليمات البرمجية أكثر تعقيداً من خلال تطبيق النمط على فئة متماسكة للغاية.
  1. علاقات نمط التصميم”Bridge design pattern”مع الأنماط الأخرى
  • عادةً ما يتم تصميم Bridge مقدماً، مما يتيح لنا تطوير أجزاء من التطبيق بشكل مستقل عن بعضها البعض. من ناحية أخرى، يتم استخدام Adapter بشكل شائع مع تطبيق موجود لجعل بعض الفئات غير المتوافقة تعمل معًا بشكل جيد.
  • Bridge, State, Strategy (وإلى حد ما Adapter) لها هياكل متشابهة جدَّاً. في الواقع، كل هذه الأنماط تعتمد على التكوين، وهو تفويض العمل إلى أشياء أخرى. ومع ذلك، فإنهم جميعا يحلّون مشاكل مختلفة. النمط ليس مجرد وصفة لتنظيم التعليمات البرمجية الخاصة بنا بطريقة معينة. ويمكنه أيضاً إبلاغ المطورين الآخرين بالمشكلة التي يحلها النمط.
  • يمكننا الجمع بين Builder وBridge : تلعب فئة المخرج دور التجريد، بينما يعمل المنشئون المختلفون كتطبيقات.
  1. الخاتمة

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

  1. المراجع

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

https://www.geeksforgeeks.org/bridge-design-pattern/?ref=lbp

Facebook
Twitter
YouTube
LinkedIn
Instagram