5.1أنماط التصميم (design patterns) والبنية النظيفة وسوليد (SOLID)
الأساسي في 30 ثانية
- الأنماط = حلول مجربة: وصفات تنظيم مثبتة (Factory والمستودع (Repository) وحقن التبعيات (injection de dépendances/DI)) + مفردات مشتركة.
- سوليد (SOLID) = 5 مبادئ: المسؤولية الواحدة والمفتوح/المغلق وليسكوف وفصل الواجهات وعكس التبعيات.
- التمييز: التطبيق بقدر حسب المشكلة — لا هندسة مفرطة ولا فوضى.
حالة مصغرة متسلسلة — رياد يهيكل متجره في قسنطينة
رياد، مطور ويب في قسنطينة، يصون متجرا صغيرا على الخط: الشيفرة تخلط استعلامات SQL و HTML وقواعد الأسعار في الملفات نفسها، وكل إصلاح يكسر شيئا آخر. يركّز الوصول إلى البيانات في مستودع (Repository)، ويحقن تبعياته بدلا من إنشائها صلبا، ويفكك صنفا كان يفعل كل شيء. هذا القسم يروي تحوله نحو شيفرة مصممة لتدوم — ويستمر الخيط في 5.2 و5.3 و5.4.
هذه الحالة نفسها تعود في الدرس والمخطط والنص الجاهز وتحدي 48 ساعة — وتستمر في 5.2 و5.3 و5.4.
1. أنماط التصميم (design patterns)
في مستوى الخبرة يصير السؤال «كيف نهيكل الشيفرة لتكون متينة وقابلة للصيانة والتطور». فأنماط التصميم (design patterns) هي حلول مجربة لمشاكل تصميم متكررة: وصفات تنظيم مثبتة من المجتمع، تجنب إعادة اختراع العجلة. الشائع في PHP: Factory (تفويض إنشاء الكائنات للفصل) والمستودع (Repository) (تركيز الوصول إلى بيانات كيان) وStrategy (خوارزميات قابلة للتبديل) وObserver (الإشعار بحدث) وحقن التبعيات (injection de dépendances/DI) (تزويد الكائن بتبعياته من الخارج — محوري في الأطر الحديثة). يجد رياد فيها مشاكله اليومية محلولة أصلا من آخرين.
ومكسب حاسم: الأنماط تعطي مفردات مشتركة — فقول «إنه مستودع (Repository)» يوصل نية تصميم. والأطر (Laravel و Symfony) تستعملها بكثافة: فتمييزها يعني فهم ما يفعله الإطار بدلا من تحمله.
2. مبادئ سوليد (SOLID)
سوليد (SOLID) خمسة مبادئ للتصميم كائني التوجه: Single Responsibility (الصنف = مسؤولية واحدة وسبب واحد للتغيير) وOpen/Closed (مفتوح للتوسيع ومغلق للتعديل: الإضافة دون كسر الموجود) وLiskov Substitution (الصنف المشتق يجب أن يعوّض أصله دون كسر السلوك) وInterface Segregation (عدة واجهات مخصصة بدلا من واجهة عامة ضخمة) وDependency Inversion (الاعتماد على التجريدات — الواجهات — بدلا من التطبيقات الملموسة). مطبقةً، تنتج شيفرة مفصولة وقابلة للتوسيع والاختبار. يبدأ رياد بـ S و D: يفكك صنفه الجامع ثم يعتمد على واجهة.
والبنية النظيفة امتداد لهذا التفكير: فصل الطبقات والفصل وقابلية القراءة. والشيفرة المحترمة لهذه المبادئ تُختبَر بسهولة — وتُطوَّر دون خوف.
3. التمييز قبل كل شيء
نقطة منظور أساسية: الأنماط وسوليد (SOLID) تُطبَّق بتمييز لا بعقيدة. فالهندسة المفرطة (أنماط معقدة وطبقات تجريد حيث يكفي حل بسيط) فخ حقيقي كالهندسة الناقصة (شيفرة فوضوية): تعقيد عديم الفائدة وشيفرة أصعب فهما وتصلب متناقض ووقت ضائع. لا يضيف رياد ثلاث طبقات لسكربت من صفحة — بل يهيكل ما يكبر ويدوم.
وهذه المفاهيم عابرة أيضا: تصلح في كل برمجة كائنية التوجه، وتتجاوز PHP. وإتقانها علامة العبور نحو الخبرة: لا نكتفي بجعل الشيفرة تعمل، بل نصممها لتدوم — مهارة تُكتسَب بالممارسة وقراءة الشيفرة الجيدة، لا سيما شيفرة الأطر.
🔎 مثال ملموس — رياد يركّز الوصول إلى البيانات
مستودع (Repository) قابل للاختبار وتبعية محقونة.
pdo->prepare('SELECT * FROM produits WHERE id = :id');
$req->execute(['id' => $id]);
$ligne = $req->fetch(PDO::FETCH_ASSOC);
return $ligne === false ? null : $ligne;
}
}
// المتحكم يستلم المستودع (حقنا) ولا ينشئه بنفسه:
// $controleur = new ProduitControleur(new ProduitRepository($pdo));
القراءة: تعيش SQL في مكان واحد، والمتحكم يعتمد على واجهة — فيمكن الاختبار بمستودع مزيف.
الدرس: المستودع (Repository) + الحقن = شيفرة مفصولة وقابلة للاختبار تتطور دون كسر.
مفردات القسم
- أنماط التصميم (design patterns)
- حلول مجربة لمشاكل تصميم متكررة، مع مفردات مشتركة.
مثال بسيط: يركّز رياد استعلامات منتجاته في مستودع (Repository).
ما ليس كذلك: قواعد إلزامية تُطبَّق في كل مكان.
رد فعل: أي مشكلة متكررة أحلها ؟
- المستودع (Repository)
- نمط يركّز الوصول إلى بيانات كيان في مكان واحد.
مثال بسيط: كل استعلامات منتجات رياد تمر عبر ProduitRepository.
ما ليس كذلك: SQL مبعثرة في العروض والمتحكمات.
رد فعل: هل SQL خاصتي مجمعة وقابلة لإعادة الاستعمال ؟
- حقن التبعيات (injection de dépendances/DI)
- تزويد الكائن بتبعياته من الخارج بدلا من إنشائها.
مثال بسيط: متحكم رياد يستلم PDO بدلا من بنائه.
ما ليس كذلك: إنشاء PDO خفي في قعر دالة.
رد فعل: هل أستطيع اختبار هذا الصنف بمزيف ؟
- سوليد (SOLID)
- خمسة مبادئ للتصميم كائني التوجه نحو شيفرة مفصولة وقابلة للصيانة.
مثال بسيط: يفكك رياد صنفه الجامع (S) ثم يعتمد على الواجهات (D).
ما ليس كذلك: قائمة تحقق تُعلَّم عمياء.
رد فعل: أي حرف من SOLID يخفف ألمي الحالي ؟
- الهندسة المفرطة
- بنية وتجريدات أكثر مما يكفي الحل البسيط.
مثال بسيط: يترك رياد سكربت صفحته بسيطا دون طبقات.
ما ليس كذلك: الشيفرة الفوضوية دون أي بنية.
رد فعل: هل يدفع هذا التجريد كلفته ؟
في التطبيق — تصميم شيفرة نظيفة وقابلة للصيانة
- اكتشفوا بعض أنماط التصميم (design patterns) الشائعة (Factory والمستودع (Repository) وحقن التبعيات) ورصدوها في شيفرة إطار (Laravel/Symfony).
- طبقوا المسؤولية الواحدة (S من SOLID): الصنف = مسؤولية واحدة؛ وفككوا صنفا يفعل أكثر من اللازم.
- طبقوا عكس التبعيات (D): اجعلوا شيفرتكم تعتمد على واجهة بدلا من صنف ملموس (أكثر مرونة وقابلية للاختبار).
- مارسوا التمييز: طبقوا البنية المناسبة للمشكلة، دون هندسة مفرطة (لا أنماط معقدة عديمة الفائدة ولا فوضى).
نص جاهز للقول — اقتراح تقسيم نظيف
«في متجرنا في قسنطينة، استعلامات SQL مخلوطة بـ HTML وكل إصلاح يكسر شيئا آخر. أقترح تركيز الوصول إلى البيانات في مستودع (Repository) وحقن التبعيات: سنستطيع الاختبار دون القاعدة وتعديل العرض دون لمس البيانات. أبدأ بصنف واحد ونقيس المكسب ثم نوسع.»
يُقال في مراجعة الشيفرة لاعتماد تقسيم تدريجي، دون وعد بإعادة كتابة كاملة.
نموذج للنسخ واللصق — شبكة مراجعة SOLID
مراجعة سوليد (SOLID) (صنف واحد)
S — المسؤولية الواحدة: هل لهذا الصنف سبب واحد للتغيير ؟ ← إن لا: ماذا نفكك ؟ ___
O — مفتوح/مغلق: لإضافة حالة هل يجب تعديل الموجود ؟ ← إن نعم: أي توسيع نتوقع ؟ ___
L — ليسكوف: هل يستطيع صنف ابن تعويض أصله ؟ ← الاختبار: ___
I — الواجهات: هل الواجهة ضخمة ؟ ← تُقسَّم إلى: ___
D — العكس: على أي ملموس يعتمد ؟ ← يُستبدَل بالواجهة: ___
فردي / ميزانية صغيرة
رياد وحده: تطبيق S و D على الصنفين الأكثر إيلاما يكفي — دون إعادة هيكلة كل شيء.
شركة صغيرة جدا / فريق مصغر
مستودع (Repository) مشترك للكيانات الحرجة: يقرأ الفريق كله البيانات ويكتبها في المكان نفسه.
شركة صغيرة ومتوسطة في قسنطينة
يضبط رياد مراجعة SOLID شهرية مع الفريق في قسنطينة: صنف يمر على الشبكة في كل مرة.
فريق يبدأ
ثنائي: أحدهما يرمز الوظيفة والآخر يراجع بالشبكة؛ ولا نضيف نمطا إلا على مشكلة حقيقية.
✓ ممارسات جيدة
- ابدؤوا بـ S (المسؤولية الواحدة) و D (عكس التبعيات): أفضل نسبة جهد/مكسب.
- اقرؤوا الشيفرة الجيدة (الأطر) لرؤية الأنماط في وضع حقيقي.
- لا تضيفوا نمطا إلا على مشكلة صيانة أو اختبار حقيقية.
✗ أخطاء شائعة
- تطبيق الأنماط في كل مكان «للاحتراف» (هندسة مفرطة).
- إساءة استعمال Singleton (حالة عامة خفية واختبارات صعبة) — ويستعمل بشح.
- الخلط بين البنية والورقية: طبقات لا تضيف شيئا تكلف فهما.
النقاط الأساسية
- أنماط التصميم (design patterns) = حلول مجربة لمشاكل تصميم متكررة (Factory والمستودع (Repository) و Strategy و Observer وحقن التبعيات)؛ ومفردات مشتركة. وتستعملها الأطر بكثافة.
- سوليد (SOLID) = 5 مبادئ للتصميم كائني التوجه: المسؤولية الواحدة والمفتوح/المغلق (التوسيع دون تعديل) وليسكوف وفصل الواجهات وعكس التبعيات (الاعتماد على التجريدات).
- مطبقةً، تنتج شيفرة مفصولة وقابلة للتوسيع والاختبار والصيانة (البنية النظيفة: طبقات مفصولة وفصل وقابلية قراءة).
- التمييز: التطبيق بقدر حسب المشكلة — فالهندسة المفرطة (بنية زائدة) فخ كالفوضى. مفاهيم عابرة (تتجاوز PHP). وعلامة العبور نحو الخبرة (التصميم لا مجرد التشغيل).
تحدي 48 ساعة — طبّق غدا
مرروا صنفا واحدا من مشروعكم على شبكة المراجعة أعلاه: أي حرف من SOLID يؤلمكم أكثر — وأي تقسيم تقترحون ؟
- أستطيع ذكر 3 أنماط واستعمال كل واحد في جملة.
- صنفي المراجَع يحترم S و D (أو أعرف ما أفككه).
- أعرف متى لا أضيف نمطا.
أسئلة شائعة
هل يجب تعلم أنماط التصميم (design patterns) وسوليد (SOLID) أم هي نظرية زائدة ؟
لا زائدة ولا تُتعلَّم دفعة واحدة: فهي أدوات تصميم مجربة تدفع في المشاريع الدائمة. تجنبكم الأنماط إعادة اختراع (سيئا) لحلول مثبتة، ويرشد SOLID نحو شيفرة قابلة للصيانة، ويعطي الاثنان مفردات مشتركة ثمينة مع الفريق. وفوق ذلك تستعمل الأطر هذه الأنماط: فمعرفتها تعني فهم Laravel و Symfony بدلا من تقليدهما. لكنها تُتعلَّم تدريجيا (نمط واحد كل مرة و S و D أولا)، وتأخذ معناها بالخبرة، وتُطبَّق بتمييز: فسكربت صغير لا يحتاج بنية. ابدؤوا برصد الأنماط في الشيفرة الجيدة وطبقوا على آلامكم الحقيقية — وستتبع النظرية الممارسة.
ما الهندسة المفرطة وكيف نجد القدر المناسب من البنية ؟
الهندسة المفرطة تصميم أعقد مما يقتضيه المشكلة: طبقات وواجهات وأنماط حيث يكفي حل بسيط. كلف حقيقية: تعقيد عديم الفائدة (صعب الفهم) وشيفرة أكثر صيانة وتصلب متناقض ووقت ضائع. الفخ الكلاسيكي: متحمس بعد تعلم الأنماط يريد تطبيقها في كل مكان. ولإيجاد القدر المناسب: انطلقوا من الألم الحقيقي (اختبار مستحيل ؟ تكرار ؟ تعديلات تكسر كل شيء ؟) واختاروا الأداة الدنيا التي تخففه؛ واتركوا الشيفرة بسيطة ما لم تؤلم؛ وراجعوا بشبكة SOLID للتحقق لا للتعليم. لا كاتدرائية لكوخ ولا كوخ لكاتدرائية.
ما أنماط التصميم (design patterns) وما فائدة سوليد (SOLID) ؟