أنماط التصميم Design Patterns؛ الأنماط البنيوية (Structural Pattern)
المعلوماتية >>>> برمجيات
تستخدم أنماط الصفوف البنيوية (class structural patterns) الوراثة لإنشاء صفوف جديدة ذات فائدة أكبر، ويُستخدَم فيها العلاقة IS-A (علاقة من نوع؛ فمثلًا الطالب هو من نوع الإنسان Student is a Person). أما في أنماط الأغراض البنيوية (object structural pattern) فهي على عكس سابقتها؛ إذ تستخدم العلاقة HAS-A فيما بينها (أي يتكون من؛ فمثلًا السيارة تتكون من محرك ومقاعد … إلخ، Car has an engine, seats … etc) (1).
سنتحدث في هذا المقال عن ثلاثة أنماط تنتمي للأنماط البنيوية، وهي: نمط التَّكييف (adapter pattern)، ونمط الواجهة الزائفة (façade pattern)، ونمط التفويض أو الوكيل (proxy pattern).
نمط التَّكييف Adapter pattern
يُستخدَم في تغيير واجهة الصنف بدون تغيير العمليات الأساسية الخاصة به.
أحد الأمثلة لتوضيح هذا النمط هو مثال قارئة الذواكر؛ فهي تعمل وسيطًا بين بطاقة الذاكرة والحاسوب المحمول؛ إذ يُوفّر الحاسوب المحمول واجهة مُوحّدة (المكان الذي تضع فيه قارئة الذواكر)، وعلى اختلاف أنواع بطاقات الذاكرة غير المتوافقة مع واجهة الحاسب المحمول الخاص بك؛ فإنك تحتاج طريقةً لتكييف بطاقة الذاكرة مع الحاسب المحمول، وهذه الطريقة هي قارئة الذواكر.
متى نستخدم هذا النمط؟
نمط الواجهة الزائفة Facade pattern
إنّ تقسيم النظام إلى عدد من الأنظمة الفرعية يساعد على تخفيف تعقيده، وهدفٌ أساسي من أهداف أنماط التصميم هو تقليل الاعتماديات بين هذه الأنظمة.
إحدى الطرائق لتحقيق هذا الهدف هي التعريف بواجهة زائفة facade object؛ إذ يزوّد من يحتاجه بواجهة برمجية مُبسّطة عن النظام الفرعي. إضافةً إلى ذلك، يسمح لك هذا النمط بإجراء تعديلات على النظام الفرعي دون التأثير في مستخدمي هذا النظام.
كمثال من الحياة؛ يمكنك تخيل أزرار التحكم الخاصة بالمايكرويف (وهي تُعبّر عن الواجهة التي تتعامل معها)، فهي تحتوي على أزرار تُبسّط تعاملك مع هذه الآلة عوضًا عن حفظك الإعدادات الخاصة بكل نوع من الأطعمة وضبطها يدويًّا، إذًا هي واجهة مُبسّطة توفر أزرارًا يتكرر استخدامها وتُبسّط تعاملك معه، فهناك زر خاص بتسخين اللحوم، وزر آخر لتسخين الأطعمة المجمدة، وهكذا. وبالطبع في حال أردت تسخين شيء ذي تعقيد أكبر؛ فلا يزال لديك إمكانية الضبط اليدوي (1، 2).
متى نستخدم هذا النمط؟
نمط التفويض أو الوكيل Proxy Pattern
يخدم هذا النمط هدفًا مهمًّا في التحكم بالوصول إلى أغراض أخرى؛ خاصةً إذا كان ذاك الغرض لم يُنشَأ بعد، أو إذا كان إنشاء غرض ما مكلف (بسبب عملية حسابية مُعقدة مثلًا)، فعندها يمكن تمثيله باستخدام وكيل proxy، بحيث تستطيع التحكم بالغرض عن طريق إنشائه مباشرة واستعماله عند جاهزيته، أو تأجيل إنشائه إلى حين الحاجة إليه (3).
مثالٌ للتوضيح: عندما تفتح صفحة ويب تحتوي على كثيرٍ من الصور والفيديوهات ويبدأ المتصفح مباشرة بتحميلها مع فتح الصفحة؛ عندها سوف يحتاج المتصفح كثيرًا من الوقت ومصادر الشبكة حتى ينتهي من تحميل الصفحة. أما إذا استخدمَ صورةً مُصغّرة (thumbnail) عن الصورة أو الفيديو (وهي تُعبّر عن الوكيل بحالتنا هذه) وأجّل تحميل الصورة أو الفيديو الأساسي إلى حين النقر عليه؛ فستصبح عملية فتح الصفحة أسرع.
متى نستخدم هذا النمط؟
تُعدّ الأنماط البنيوية أغلفةً (wrappers) لأغراض أخرى؛ إذ يعمل هذا الغلاف على تعديل الواجهة البرمجية من أجل تبسيطها، أو إضافة عمليات جديدة بتوسيع الغرض الأساسي، أو تقييد الوصول إليه، إضافةً إلى تمكين نظامين غير متوافقين بأن يعملا معًا دون مشكلات.
هناك أنماط بنيوية أخرى عديدة لم نذكرها، منها: نمط المُرّكب (Composite pattern)، ونمط وزن الذبابة (Flyweight)، ونمط الجسر (Bridge) وغيرها، ولكن تحدثنا عن الأنماط الثلاثة الأكثر استخدامًا.
المصادر:
2- Singleton [Internet]. Cs.unc.edu. [cited 22 November 2020]. Available from: هنا;
3- C. Martin R. Design Principles and Design Patterns [Internet]. Staff.cs.utu.fi. 2000 [cited 19 April 2021]. Available from: هنا;