البرنامج التعليمي

SOLID ما هي المبادئ الخمسة للبرمجة الشيئية

SOLID هو اختصار يشير إلى المبادئ الخمسة للتصميم الموجه للكائنات (OOD أو OOP). هذه إرشادات يمكن للمطورين استخدامها لإنشاء برامج يسهل إدارتها وصيانتها وتوسيعها. إن فهم هذه المفاهيم سيجعلك مطورًا أفضل ويساعدك على تجنب مشاكل إدارة البرامج. ماذا يعني أن تكون مبرمجًا جيدًا؟

أي شخص لديه بعض الخبرة في برمجة البرمجيات يحكم على كود البرنامج الذي كتبه الآخرون ، باستخدام معايير الحكم على أساس مسار حياتهم المهنية.

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

  • البساطة في قراءة الكود.
  • ما مدى احتمالية عمل الكود الخاص بهم والتطور بمرور الوقت.

لحسن الحظ ، هناك بعض الأساسيات أو المبادئ التي تجعل من السهل أن تكون أفضل في البرمجة.

يشير الاختصار SOLID إلى:
S: مبدأ المسؤولية الفردية
O: مبدأ مفتوح
L: مبدأ استبدال Liskov
I: مبدأ فصل الواجهة
D: مبدأ انعكاس التبعيات

لنبدأ بالخوض في أول مبدأ SOLID ، ألا وهو

مبدأ المسؤولية الفردية

يجب أن يكون للفصل (أو الوحدة) سبب واحد فقط للتغيير والتطور.

المفهوم بحد ذاته بسيط للغاية ، ولكن لتحقيق هذه البساطة ، يمكن أن يكون مسار التنفيذ معقدًا للغاية. يجب أن يكون للفصل سبب واحد فقط للتغيير.

لكن لماذا؟ 

لماذا من المهم أن يكون لديك سبب واحد فقط للتغيير؟

على سبيل المثال ، إذا كان هناك سببان مختلفان للتغيير ، فمن الممكن أن يعمل فريقان مختلفان على نفس الرمز لسببين مختلفين. سيتعين على كل منهم تنفيذ الحل الخاص به ، والذي في حالة اللغة المترجمة (مثل C ++ أو C # أو Java) ، يمكن أن يؤدي إلى وحدات غير متوافقة مع الفرق الأخرى أو أجزاء أخرى من التطبيق.

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

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

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

بعض الأمثلة على الوحدات واستخدامها:

  • وحدة الصيانة: يتكون المستخدم من مسؤولي قواعد البيانات ومهندسي البرمجيات.
  • وحدة التقارير: يتكون المستخدم من العاملين في المكاتب والمحاسبين والإنتاج.
  • وحدة حساب الدفع لنظام إدارة الرواتب: يمكن أن يشمل المستخدمون محامين ومديرين ومحاسبين.
  • وحدة البحث عن نص لنظام إدارة المكتبات: يمكن أن يمثل المستخدم من قبل أمين المكتبة أو من قبل زوار وعملاء المكتبة نفسها.

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

يبدو من المعقول تحديد الأدوار ، بدلاً من الأشخاص أو المستخدمين.

لذلك:

  • استخدام نظام البرمجيات defiيشرح أسباب التغيير.
  • المسؤولية هي مجموعة من الوظائف التي تلبي احتياجات فاعل معين ، أي مستخدم النظام ؛
  • الجهات الفاعلة ، يصبح المستخدم مصدرًا للتغيير لعائلة الوظائف التي يجب أن تلبي حاجة المستخدم ؛
  • تطور احتياجات المستخدم ، يوجه تطور الوظائف ؛

دعونا نرى بعض الأمثلة

لنفترض أن لدينا فصلًا عن الكتاب يلخص مفهوم الكتاب ووظائفه.

كتاب الصف {

    وظيفة getTitle () {

        عودة "كتاب عظيم" ؛

    }

    وظيفة getAuthor () {

        عودة "أليساندرو باريكو" ؛

    }

    الدالة nextpage () {

        // الصفحة التالية

    }

    وظيفة printCurrent Page () {

        صدى "محتوى الصفحة الحالية" ؛

    }

}

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

ومع ذلك ، هناك مشكلة صغيرة. 

بالتفكير في الممثلين المشاركين في إدارة كائن الكتاب ، من يكونون؟ 

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

لذلك لدينا ممثلان مختلفان للغاية يتفاعلان مع الفصل

باختصار ، يمزج هذا الفصل بين:

  • منطق الأعمال مع 
  • العرض التقديمي 

يمكن أن يكون هذا مشكلة لأنه ينتهك مبدأ المسؤولية الفردية (SRP). 

كيف يمكننا تغيير ، كيف يمكننا تحسين هذا القانون لاحترام مبدأ المسؤولية الفردية؟

ألق نظرة على الكود التالي:

كتاب الصف {

    وظيفة getTitle () {

        عودة "Oceano Mare" ؛

    }

    وظيفة getAuthor () {

        عودة "أليساندرو باريكو" ؛

    }

    وظيفة قلب الصفحة () {

        // الصفحة التالية

    }

    وظيفة getCurrentPage () {

        صدى "محتوى الصفحة الحالية" ؛

    }

}

طابعة الواجهة {

    وظيفة printPage (صفحة $) ؛

النشرة الإخبارية
لا تفوّت أهم أخبار الابتكار. قم بالتسجيل لتلقيهم عن طريق البريد الإلكتروني.

}

فئة StampaLibro تنفذ الطابعة {

    وظيفة printPages (صفحة $) {

        صدى $ الصفحة؛

    }

}

 

فئة HtmlPrinter تنفذ الطابعة {

    وظيفة printPages (صفحة $) {

        صدى صوت ' ". الصفحة $. " "؛

    }

}

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

لنلق نظرة على مثال آخر:

مثال مشابه للمثال أعلاه هو عندما يمكن للكائن حفظ نفسه واسترداد نفسه من العرض التقديمي.

كتاب الصف {

    وظيفة getTitle () {

        عودة "Oceano Mare" ؛

    }

    وظيفة getAuthor () {

        عودة "أليساندرو باريكو" ؛

    }

    وظيفة قلب الصفحة () {

        // الصفحة التالية

    }

    وظيفة getCurrentPage () {

        إرجاع "محتوى الصفحة الحالية" ؛

    }

    وظيفة حفظ () {

        اسم الملف $ = '/ documents /'. $ this-> getTitolo (). "-". $ this-> getAuthor ()؛

        file_put_contents ($ filename، serialize ($ this))؛

    }

}

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

كتاب الصف {

    وظيفة getTitle () {

        عودة "Oceano Mare" ؛

    }

    وظيفة getAuthor () {

        عودة "أليساندرو باريكو" ؛

    }

    وظيفة قلب الصفحة () {

        // الصفحة التالية

    }

    وظيفة getCurrentPage () {

        إرجاع "محتوى الصفحة الحالية" ؛

    }

}

فئة SimpleFilePersistance {

    وظيفة حفظ (كتاب $ كتاب) {

        اسم الملف $ = '/ documents /'. $ book-> getTitle (). "-". $ book-> getAuthor ()؛

        file_put_contents ($ filename، serialize ($ book))؛

    }

}

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

تابع بقراءة المبدأ الثاني مفتوح / مغلق ->

Ercole Palmeri

النشرة الإخبارية
لا تفوّت أهم أخبار الابتكار. قم بالتسجيل لتلقيهم عن طريق البريد الإلكتروني.

المقالات الأخيرة

يوقع الناشرون وOpenAI اتفاقيات لتنظيم تدفق المعلومات التي تتم معالجتها بواسطة الذكاء الاصطناعي

أعلنت صحيفة فاينانشيال تايمز يوم الاثنين الماضي عن صفقة مع OpenAI. "فاينانشيال تايمز" ترخص صحافتها ذات المستوى العالمي...

أبريل 30 2024

المدفوعات عبر الإنترنت: إليك كيف تجعلك خدمات البث تدفع إلى الأبد

يدفع الملايين من الأشخاص مقابل خدمات البث، ويدفعون رسوم الاشتراك الشهرية. من الشائع أنك…

أبريل 29 2024

يتميز Veeam بالدعم الأكثر شمولاً لبرامج الفدية، بدءًا من الحماية وحتى الاستجابة والاسترداد

سوف تستمر شركة Coveware by Veeam في تقديم خدمات الاستجابة لحوادث الابتزاز السيبراني. ستوفر Coveware إمكانات الطب الشرعي والمعالجة...

أبريل 23 2024

الثورة الخضراء والرقمية: كيف تعمل الصيانة التنبؤية على تغيير صناعة النفط والغاز

تُحدث الصيانة التنبؤية ثورة في قطاع النفط والغاز، من خلال اتباع نهج مبتكر واستباقي لإدارة المحطات.

أبريل 22 2024

اقرأ الابتكار بلغتك

النشرة الإخبارية
لا تفوّت أهم أخبار الابتكار. قم بالتسجيل لتلقيهم عن طريق البريد الإلكتروني.

تابعنا