Blog

مبادئ التصميم الكينوني الصلبة

solid-webepower

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

ما هو S.O.L.I.D؟

S – مبدأ المسؤولية الفردية
O – مبدأ مفتوح مغلق
مبدأ استبدال Liskov
I – مبدأ فصل الواجهة
د- مبدأ انعكاس التبعية

دعونا نفهم كل مبدأ على حدة لفهم لماذا يمكن أن تساعد S.O.L.I.D في جعلنا مطورين أفضل.

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

نص على أنه “يجب أن يكون للفصل سبب واحد فقط للتغيير ، مما يعني أنه يجب أن يكون للفصل وظيفة واحدة فقط للقيام بها”

دعونا نفهم هذا بمثال.

تخيل أن لدينا واجهة مستخدمين مثل هذا:

 واجهة مستخدم واجهة المستخدم
{
    setId الوظيفة العامة ($ id) ؛
    الوظيفة العامة getId () ،
    setName الوظيفة العامة (اسم $) ؛
    findById الوظيفة العامة ($ id) ؛
    إنشاء الوظيفة العامة () ؛
    إدراج الوظيفة العامة () ؛
    تحديث الوظيفة العامة () ؛
    حذف الوظيفة العامة () ؛
}

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

نبسب ؛

حتى نتمكن من حل هذه المشكلة عن طريق إنشاء واجهتين مختلفتين ، واجهة المستخدم و
UserMapperInterface

 واجهة UserMapperInterface
{
    findById الوظيفة العامة ($ id) ؛
    إنشاء الوظيفة العامة () ؛
    إدراج الوظيفة العامة (UserInterface $ user) ؛
    تحديث الوظيفة العامة (UserInterface $ user) ؛
    حذف الوظيفة العامة (معرف $) ؛
}

واجهة المستخدم
{
    setId الوظيفة العامة ($ id) ؛
    الوظيفة العامة getId () ،
    setName الوظيفة العامة (اسم $) ؛
    تعيين الوظيفة العامة البريد الإلكتروني (البريد الإلكتروني دولار) ؛
    الوظيفة العامة getEmail () ؛
}

2. مبدأ مفتوح مغلق

وذكر أن “الكائنات أو الكيانات يجب أن تكون مفتوحة للتمديد ، ولكن مغلقة للتعديل”.

هذا يعني أنه يجب أن تكون الفئة قابلة للتمديد بسهولة دون تعديل الفئة نفسها.

دعنا نفهم هذا ونفترض أن لدينا فئة لوحة تحتوي على مستطيلات ونحسب مساحة المستطيلات.

 فئة مستطيل
{
    العرض العام بالدولار الأمريكي ؛
    ارتفاع الدولار العام ؛
}
مجلس الصف
{
    المستطيلات $ العامة []؛
    حساب الوظيفة العامة () {
        المنطقة $ = 0 ؛
        foreach ($ this- & gt؛ Rectangleles as $ rectangle) {
            $ area + = $ rectangle- & gt؛ width * $ rectangle- & gt؛ height؛
        }
    }
}

ولكن الآن إذا كنت من المتطلبات الجديدة التي تحتاج إلى إضافة دوائر إلى اللوحة.

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

 شكل الواجهة {
    منطقة الوظيفة العامة () ؛
}

فئة المستطيل تنفذ الشكل
{
    منطقة الوظيفة العامة () {
        إرجاع $ this- & GT؛ width * $ this- & GT؛ height؛
    }
}

فئة الدائرة تنفذ الشكل
{
    منطقة الوظيفة العامة () {
        إرجاع $ this- & GT؛ radius * $ this- & GT؛ radius * pi ()؛
    }
}

مجلس الصف
{
    حساب الوظيفة العامة () {
        المنطقة $ = 0 ؛
        foreach ($ this- & gt؛ Forms as $ shape) {
            $ area + = $ shape- & gt؛ area ()؛
        }
    }
}

3. مبدأ استبدال Liskove

وذكر أن “دع q (x) تكون خاصية حول كائنات من النوع x من النوع T. ثم يجب إثبات q (y) للكائنات y من النوع S حيث S هي نوع فرعي من T”.

وهذا يعني أن كل فئة فرعية / فئة مشتقة يجب أن تكون قابلة للاستبدال بفئتها الأساسية / الأصل.

دعونا نفهم بمثال. في هذه الحالة ، لدينا صنف Rectangle ونريد الآن إنشاء فئة مربعة تمتد من Rectangle.

 فئة مستطيل
{
    وظيفة عامة setWidth ($ w) {$ this- & gt؛ width = $ w؛ }
    الوظيفة العامة setHeight ($ h) {$ this- & gt؛ height = $ h؛ }
    الوظيفة العامة getArea () {return $ this- & gt؛ height * $ this- & gt؛ width؛ }
}

يمتد مربع فئة المستطيل
{
    وظيفة عامة setWidth ($ w) {$ this- & gt؛ width = $ w؛ $ this- & GT ؛ الارتفاع = $ w ؛ }
    الوظيفة العامة setHeight ($ h) {$ this- & gt؛ height = $ h؛ $ this- & GT ؛ العرض = $ h ؛
}

الآن يمكننا إنشاء دالة لحساب الفئات.

 وظيفة areaOfRectangle () {
    المستطيل $ = مستطيل جديد () ؛
    $ r- & gt؛ setWidth (7) ؛ $ r- & gt؛ setHeight (3) ؛
    $ r- & gt؛ getArea ()؛ // 21
}

كما يقول LSP ، يجب أن نكون قادرين على تغيير المستطيل بالمربع:

 وظيفة areaOfRectangle () {
    المستطيل $ = مربع جديد () ؛
    $ r- & gt؛ setWidth (7) ؛ $ r- & gt؛ setHeight (3) ؛
    $ r- & gt؛ getArea ()؛ // 9
}

كما قلنا “يجب أن نتأكد من أن فئات Square تعمل على توسيع المستطيل دون تغيير سلوكهم”. ولكن نظرًا لأننا نتلقى الناتج 21 الذي لا يساوي 9

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

 واجهة Quard
{
    تعيين الوظيفة العامةالارتفاع ($ h) ؛
    setWidht الوظيفة العامة ($ w) ؛
    وظيفة عامة getArea () ؛
}
فئة المستطيل تنفذ Quard ؛

كلاس سكوير تنفذ Quard ؛

4. مبدأ فصل الواجهة

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

دعونا نفهم هذا ونفكر في الوكالة الرقمية التي لديها عمال ، لذلك أقوم بإنشاء عامل الواجهة.

 عامل الواجهة {
    takeBreak () الوظيفة العامة
    رمز الوظيفة العامة ()
    callToClient () الوظيفة العامة
    حضور الوظيفة العامة الاجتماعات ()
    وظيفة عامة getPaid ()
}

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

 مدير الصف ينفذ العامل
{
    رمز الوظيفة العامة () {return false؛ }
}

فئة مطور تنفذ عامل
{
    الوظيفة العامة callToClient () {echo $ swear_word؛ }
}

الآن يجب علينا إنشاء المزيد من الواجهات.

 عامل الواجهة
{
    takeBreak () الوظيفة العامة
    وظيفة عامة getPaid ()
}

واجهة المبرمج {
    رمز الوظيفة العامة ()
}

واجهة ClientFacer {
    callToClient () الوظيفة العامة
    حضور الوظيفة العامة الاجتماعات ()
}

يقوم مختبري الفصل بتنفيذ عامل ، مبرمج {}

مدير الصف ينفذ العامل ، ClientFacer {}

5. مبدأ انعكاس التبعية

وذكر أن “الكيانات يجب أن تعتمد على التجريد وليس على الملموسة. تنص على أن الوحدة عالية المستوى يجب ألا تعتمد على التجريد ”

دعونا نفهم هذا المبدأ ولدينا فئة العمال ، وهي المستوى العالي ثم فئة تسمى العامل. يمكن للمدير جعل العامل يعمل.

 عامل الفصل
{
    عمل الوظيفة العامة () {}
}

مدير فئة
{
    عامل خاص دولار؛
    setWorker الوظيفة العامة ($ w) {
        $ this- & GT ؛ العامل = $ w ؛
    }

    إدارة الوظائف العامة () {
        $ this- & gt؛ worker- & gt؛ work ()؛
    }
}

الآن نحن بحاجة إلى إضافة نوع جديد من العمال المتخصصين ، نقوم بإنشاء فئة جديدة من العمال المتخصصين لهذا الغرض

 فئة SpecializedWorker
{
    عمل الوظيفة العامة () {}
}

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

 موظف الواجهة
{
    عمل الوظيفة العامة ()؛
}

عامل الطبقة ينفذ الموظف
{
    عمل الوظيفة العامة () {}
}
فئة SpecializedWorker ينفذ الموظف
{
    عمل الوظيفة العامة () {}
}

خاتمة

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

إذا كان لديك أي شك أو استفسار ، فلا تتردد في الاتصال بنا أو ترك استفسارك وسنعاود الاتصال بك قريبًا. نريد أن نسمع منك.